From 7f14ec2d8eeffcfc2ee045c99ecc47ab7e675c51 Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 08:39:35 +0100 Subject: [PATCH 01/21] feat: new option to ignore certain files --- lua/esqueleto/config.lua | 2 ++ lua/esqueleto/utils.lua | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lua/esqueleto/config.lua b/lua/esqueleto/config.lua index 16b37d9..2b4b265 100644 --- a/lua/esqueleto/config.lua +++ b/lua/esqueleto/config.lua @@ -4,6 +4,7 @@ M.default_config = { autouse = true, directories = { vim.fn.stdpath("config") .. "/skeletons" }, patterns = {}, + ignore = function (f) return vim.fn.fnamemodify(f, ':t') == '.DS_Store' end, } M.updateconfig = function(config) @@ -15,6 +16,7 @@ M.updateconfig = function(config) autouse = { config.autouse, 'boolean' }, directories = { config.directories, 'table' }, patterns = { config.patterns, 'table' }, + ignore = { config.ignore, 'function' }, }) return config diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index 3afd639..48312e2 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -8,7 +8,11 @@ M.writetemplate = function(file) end end -M.gettemplates = function(pattern, alldirectories) +M.isignored = function (ignore, filepath) + return ignore(filepath) +end + +M.gettemplates = function(pattern, alldirectories, ignore) local templates = {} -- Count directories that contain templates for pattern @@ -25,10 +29,12 @@ M.gettemplates = function(pattern, alldirectories) for filepath in vim.fs.dir(directory .. pattern .. '/') do filepath = directory .. pattern .. "/" .. filepath local name = vim.fs.basename(filepath) - if ndirs > 1 then - name = vim.fn.simplify(directory) .. " :: " .. name + if not M.isignored(ignore, name) then + if ndirs > 1 then + name = vim.fn.simplify(directory) .. " :: " .. name + end + templates[name] = filepath end - templates[name] = filepath end end end @@ -83,7 +89,7 @@ M.inserttemplate = function(opts) end -- Get templates for selected pattern - local templates = M.gettemplates(pattern, opts.directories) + local templates = M.gettemplates(pattern, opts.directories, opts.ignore) -- Pop-up selection UI M.selecttemplate(templates, opts) From 3b2373845d8c05651defe40c3e149e5c136e399c Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 08:42:16 +0100 Subject: [PATCH 02/21] Revert "feat: new option to ignore certain files" This reverts commit 7f14ec2d8eeffcfc2ee045c99ecc47ab7e675c51. --- lua/esqueleto/config.lua | 2 -- lua/esqueleto/utils.lua | 16 +++++----------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/lua/esqueleto/config.lua b/lua/esqueleto/config.lua index 2b4b265..16b37d9 100644 --- a/lua/esqueleto/config.lua +++ b/lua/esqueleto/config.lua @@ -4,7 +4,6 @@ M.default_config = { autouse = true, directories = { vim.fn.stdpath("config") .. "/skeletons" }, patterns = {}, - ignore = function (f) return vim.fn.fnamemodify(f, ':t') == '.DS_Store' end, } M.updateconfig = function(config) @@ -16,7 +15,6 @@ M.updateconfig = function(config) autouse = { config.autouse, 'boolean' }, directories = { config.directories, 'table' }, patterns = { config.patterns, 'table' }, - ignore = { config.ignore, 'function' }, }) return config diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index 48312e2..3afd639 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -8,11 +8,7 @@ M.writetemplate = function(file) end end -M.isignored = function (ignore, filepath) - return ignore(filepath) -end - -M.gettemplates = function(pattern, alldirectories, ignore) +M.gettemplates = function(pattern, alldirectories) local templates = {} -- Count directories that contain templates for pattern @@ -29,12 +25,10 @@ M.gettemplates = function(pattern, alldirectories, ignore) for filepath in vim.fs.dir(directory .. pattern .. '/') do filepath = directory .. pattern .. "/" .. filepath local name = vim.fs.basename(filepath) - if not M.isignored(ignore, name) then - if ndirs > 1 then - name = vim.fn.simplify(directory) .. " :: " .. name - end - templates[name] = filepath + if ndirs > 1 then + name = vim.fn.simplify(directory) .. " :: " .. name end + templates[name] = filepath end end end @@ -89,7 +83,7 @@ M.inserttemplate = function(opts) end -- Get templates for selected pattern - local templates = M.gettemplates(pattern, opts.directories, opts.ignore) + local templates = M.gettemplates(pattern, opts.directories) -- Pop-up selection UI M.selecttemplate(templates, opts) From 6dd79f2537825e7b56ca063be30ca7fa14e5aae8 Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 08:47:05 +0100 Subject: [PATCH 03/21] feat: new option to ignore certain files TODO: update README and doc --- lua/esqueleto/config.lua | 2 ++ lua/esqueleto/utils.lua | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lua/esqueleto/config.lua b/lua/esqueleto/config.lua index 16b37d9..2b4b265 100644 --- a/lua/esqueleto/config.lua +++ b/lua/esqueleto/config.lua @@ -4,6 +4,7 @@ M.default_config = { autouse = true, directories = { vim.fn.stdpath("config") .. "/skeletons" }, patterns = {}, + ignore = function (f) return vim.fn.fnamemodify(f, ':t') == '.DS_Store' end, } M.updateconfig = function(config) @@ -15,6 +16,7 @@ M.updateconfig = function(config) autouse = { config.autouse, 'boolean' }, directories = { config.directories, 'table' }, patterns = { config.patterns, 'table' }, + ignore = { config.ignore, 'function' }, }) return config diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index 3afd639..8bdd23b 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -2,6 +2,10 @@ local M = {} _G.esqueleto_inserted = {} +M.isignored = function(ignore, filepath) + return ignore(filepath) +end + M.writetemplate = function(file) if file ~= nil then vim.cmd("0r " .. file) @@ -36,6 +40,36 @@ M.gettemplates = function(pattern, alldirectories) return templates end +M.getunignoredtemplates = function(pattern, alldirectories, ignore) + local templates = {} + + -- Count directories that contain templates for pattern + local ndirs = 0 + for _, directory in pairs(alldirectories) do + directory = vim.fn.fnamemodify(directory, ':p') -- expand path + ndirs = ndirs + vim.fn.isdirectory(directory .. pattern .. '/') + end + + -- Get templates for pattern + for _, directory in ipairs(alldirectories) do + directory = vim.fn.fnamemodify(directory, ':p') -- expand path + if vim.fn.isdirectory(directory .. pattern .. '/') == 1 then + for filepath in vim.fs.dir(directory .. pattern .. '/') do + filepath = directory .. pattern .. "/" .. filepath + if not M.isignored(ignore, filepath) then + local name = vim.fs.basename(filepath) + if ndirs > 1 then + name = vim.fn.simplify(directory) .. " :: " .. name + end + templates[name] = filepath + end + end + end + end + + return templates +end + M.selecttemplate = function(templates, opts) -- Check if templates exist if vim.tbl_isempty(templates) then @@ -83,7 +117,7 @@ M.inserttemplate = function(opts) end -- Get templates for selected pattern - local templates = M.gettemplates(pattern, opts.directories) + local templates = M.getunignoredtemplates(pattern, opts.directories, opts.ignore) -- Pop-up selection UI M.selecttemplate(templates, opts) From b3ebcdf79749db9ed5d4b706a0e906c468825c39 Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 20:49:27 +0100 Subject: [PATCH 04/21] chore: init constants --- lua/esqueleto/constants.lua | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 lua/esqueleto/constants.lua diff --git a/lua/esqueleto/constants.lua b/lua/esqueleto/constants.lua new file mode 100644 index 0000000..c1f1dd6 --- /dev/null +++ b/lua/esqueleto/constants.lua @@ -0,0 +1,7 @@ +local M = {} + +-- OS-specific ignoring files, from `https://www.toptal.com/developers/gitignore/api/windows,macos,linux` +-- Index: Thu Sep 28 20:45:56 BST 2023 +M.ignored_files = { '*~', '.fuse_hidden*', '.directory', '.Trash-*', '.nfs*', '.DS_Store', '.AppleDouble', '.LSOverride', 'Icon', '._*', '.DocumentRevisions-V100', '.fseventsd', '.Spotlight-V100', '.TemporaryItems', '.Trashes', '.VolumeIcon.icns', '.com.apple.timemachine.donotpresent', '.AppleDB', '.AppleDesktop', 'Network Trash Folder', 'Temporary Items', '.apdisk', '*.icloud', 'Thumbs.db', 'Thumbs.db:encryptable', 'ehthumbs.db', 'ehthumbs_vista.db', '*.stackdump', '[Dd]esktop.ini', '$RECYCLE.BIN/', '*.cab', '*.msi', '*.msix', '*.msm', '*.msp', '*.lnk' } + +return M From a6a7c3d482c739a21e57302a1b7ef27a08a37497 Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 21:30:28 +0100 Subject: [PATCH 05/21] chore: revise user options; almost finish filter --- lua/esqueleto/config.lua | 6 +++-- lua/esqueleto/utils.lua | 50 ++++++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/lua/esqueleto/config.lua b/lua/esqueleto/config.lua index 2b4b265..665af85 100644 --- a/lua/esqueleto/config.lua +++ b/lua/esqueleto/config.lua @@ -4,7 +4,8 @@ M.default_config = { autouse = true, directories = { vim.fn.stdpath("config") .. "/skeletons" }, patterns = {}, - ignore = function (f) return vim.fn.fnamemodify(f, ':t') == '.DS_Store' end, + use_os_ignore = true, + extra_ignore = {}, } M.updateconfig = function(config) @@ -16,7 +17,8 @@ M.updateconfig = function(config) autouse = { config.autouse, 'boolean' }, directories = { config.directories, 'table' }, patterns = { config.patterns, 'table' }, - ignore = { config.ignore, 'function' }, + use_os_ignore = { config.use_os_ignore, 'boolean' }, + extra_ignore = { config.ignore, { 'table', 'function' } }, }) return config diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index 8bdd23b..b309e7b 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -2,10 +2,6 @@ local M = {} _G.esqueleto_inserted = {} -M.isignored = function(ignore, filepath) - return ignore(filepath) -end - M.writetemplate = function(file) if file ~= nil then vim.cmd("0r " .. file) @@ -40,8 +36,47 @@ M.gettemplates = function(pattern, alldirectories) return templates end -M.getunignoredtemplates = function(pattern, alldirectories, ignore) +local any = function (f, t) + for _, e in pairs(t) do + if f(e) then + return true + end + end + + return false +end + +-- Determine if a file matches a gitignore glob pattern +-- TODO +local match_gitignore = function (filepath, gitignore_pattern) + error 'TODO' +end + +-- Determine if a file should be ignored, +-- according to user's choice +local isignored = function (filepath, extra_ignore, use_os_ignore) + local is_user_ignored = (function () + if type(extra_ignore) == 'function' then + return extra_ignore(filepath) + else + return any(function (pat) return match_gitignore(filepath, pat) end, extra_ignore) + end + end)() + + local is_os_ignored = (function () + if not use_os_ignore then return false end + local os_ignore = require('esqueleto.constants').ignored_files + return any(function (pat) return match_gitignore(filepath, pat) end, os_ignore) + end)() + + return is_user_ignored or is_os_ignored +end + +M.getunignoredtemplates = function(pattern, opts) local templates = {} + local alldirectories = opts.directories + local extra_ignore = opts.extra_ignore + local use_os_ignore = opts.use_os_ignore -- Count directories that contain templates for pattern local ndirs = 0 @@ -56,7 +91,8 @@ M.getunignoredtemplates = function(pattern, alldirectories, ignore) if vim.fn.isdirectory(directory .. pattern .. '/') == 1 then for filepath in vim.fs.dir(directory .. pattern .. '/') do filepath = directory .. pattern .. "/" .. filepath - if not M.isignored(ignore, filepath) then + local ignored = isignored(filepath, extra_ignore, use_os_ignore) + if not ignored then local name = vim.fs.basename(filepath) if ndirs > 1 then name = vim.fn.simplify(directory) .. " :: " .. name @@ -117,7 +153,7 @@ M.inserttemplate = function(opts) end -- Get templates for selected pattern - local templates = M.getunignoredtemplates(pattern, opts.directories, opts.ignore) + local templates = M.getunignoredtemplates(pattern, opts) -- Pop-up selection UI M.selecttemplate(templates, opts) From 85246f013938510346c54581eb79439aa0d035bc Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 21:49:30 +0100 Subject: [PATCH 06/21] finish filter --- lua/esqueleto/utils.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index b309e7b..5865540 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -47,9 +47,10 @@ local any = function (f, t) end -- Determine if a file matches a gitignore glob pattern --- TODO +-- by converting to regex, then vim.regex API. local match_gitignore = function (filepath, gitignore_pattern) - error 'TODO' + local regpat = vim.fn.glob2regpat(gitignore_pattern) -- ^$ automatically added + return vim.regex(regpat):match_str(filepath) ~= nil end -- Determine if a file should be ignored, From 1f3675b6951e867a7d758859238ac328310cd61a Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 21:54:36 +0100 Subject: [PATCH 07/21] fix: typo --- lua/esqueleto/config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/esqueleto/config.lua b/lua/esqueleto/config.lua index 665af85..0f45f7d 100644 --- a/lua/esqueleto/config.lua +++ b/lua/esqueleto/config.lua @@ -18,7 +18,7 @@ M.updateconfig = function(config) directories = { config.directories, 'table' }, patterns = { config.patterns, 'table' }, use_os_ignore = { config.use_os_ignore, 'boolean' }, - extra_ignore = { config.ignore, { 'table', 'function' } }, + extra_ignore = { config.extra_ignore, { 'table', 'function' } }, }) return config From 6bd9144162830b775fa7325eeb54b8bcd317b3e7 Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 22:44:07 +0100 Subject: [PATCH 08/21] chore: partially fix `match_gitignore` Now seem to work but hackish still --- lua/esqueleto/utils.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index 5865540..a3e94dd 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -49,8 +49,15 @@ end -- Determine if a file matches a gitignore glob pattern -- by converting to regex, then vim.regex API. local match_gitignore = function (filepath, gitignore_pattern) - local regpat = vim.fn.glob2regpat(gitignore_pattern) -- ^$ automatically added - return vim.regex(regpat):match_str(filepath) ~= nil + local regpat = vim.fn.glob2regpat(gitignore_pattern):sub(2) -- manually remove ^; hackish + local start, finish = vim.regex(regpat):match_str(filepath) + local res = (function () + if start == nil or finish == nil then return false end + if start == finish then return false end -- empty match, won't do + return finish == #filepath + end)() + + return res end -- Determine if a file should be ignored, From a97cda19673ece5276706b7cad0768464fa16728 Mon Sep 17 00:00:00 2001 From: Futar Date: Fri, 29 Sep 2023 15:41:44 +0100 Subject: [PATCH 09/21] chore: use more sensible approach for ignored pats also rename ignore-patterns constant --- lua/esqueleto/constants.lua | 2 +- lua/esqueleto/utils.lua | 74 +++++++++++++------------------------ 2 files changed, 27 insertions(+), 49 deletions(-) diff --git a/lua/esqueleto/constants.lua b/lua/esqueleto/constants.lua index c1f1dd6..e33a4c6 100644 --- a/lua/esqueleto/constants.lua +++ b/lua/esqueleto/constants.lua @@ -2,6 +2,6 @@ local M = {} -- OS-specific ignoring files, from `https://www.toptal.com/developers/gitignore/api/windows,macos,linux` -- Index: Thu Sep 28 20:45:56 BST 2023 -M.ignored_files = { '*~', '.fuse_hidden*', '.directory', '.Trash-*', '.nfs*', '.DS_Store', '.AppleDouble', '.LSOverride', 'Icon', '._*', '.DocumentRevisions-V100', '.fseventsd', '.Spotlight-V100', '.TemporaryItems', '.Trashes', '.VolumeIcon.icns', '.com.apple.timemachine.donotpresent', '.AppleDB', '.AppleDesktop', 'Network Trash Folder', 'Temporary Items', '.apdisk', '*.icloud', 'Thumbs.db', 'Thumbs.db:encryptable', 'ehthumbs.db', 'ehthumbs_vista.db', '*.stackdump', '[Dd]esktop.ini', '$RECYCLE.BIN/', '*.cab', '*.msi', '*.msix', '*.msm', '*.msp', '*.lnk' } +M.ignored_patterns = { '*~', '.fuse_hidden*', '.directory', '.Trash-*', '.nfs*', '.DS_Store', '.AppleDouble', '.LSOverride', 'Icon', '._*', '.DocumentRevisions-V100', '.fseventsd', '.Spotlight-V100', '.TemporaryItems', '.Trashes', '.VolumeIcon.icns', '.com.apple.timemachine.donotpresent', '.AppleDB', '.AppleDesktop', 'Network Trash Folder', 'Temporary Items', '.apdisk', '*.icloud', 'Thumbs.db', 'Thumbs.db:encryptable', 'ehthumbs.db', 'ehthumbs_vista.db', '*.stackdump', '[Dd]esktop.ini', '$RECYCLE.BIN/', '*.cab', '*.msi', '*.msix', '*.msm', '*.msp', '*.lnk' } return M diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index a3e94dd..b1b9619 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -36,70 +36,48 @@ M.gettemplates = function(pattern, alldirectories) return templates end -local any = function (f, t) - for _, e in pairs(t) do - if f(e) then - return true - end +M.getunignoredtemplates = function(pattern, opts) + local list_ignored = function (dir, ignored_pats) + return vim.tbl_flatten(vim.tbl_map(function (pat) + return vim.fn.globpath(dir, pat, true, true, true) + end, ignored_pats)) end - return false -end + local list_os_ignored_files = function (dir) + return list_ignored(dir, require('esqueleto.constants').ignored_patterns) + end --- Determine if a file matches a gitignore glob pattern --- by converting to regex, then vim.regex API. -local match_gitignore = function (filepath, gitignore_pattern) - local regpat = vim.fn.glob2regpat(gitignore_pattern):sub(2) -- manually remove ^; hackish - local start, finish = vim.regex(regpat):match_str(filepath) - local res = (function () - if start == nil or finish == nil then return false end - if start == finish then return false end -- empty match, won't do - return finish == #filepath - end)() + local list_user_ignored_files = list_ignored - return res -end - --- Determine if a file should be ignored, --- according to user's choice -local isignored = function (filepath, extra_ignore, use_os_ignore) - local is_user_ignored = (function () - if type(extra_ignore) == 'function' then - return extra_ignore(filepath) + local templates = {} + local use_os_ignore = opts.use_os_ignore + local extra_ignore_pats, extra_ignore_func = (function () + if type(opts.extra_ignore) == 'function' then + return {}, opts.extra_ignore else - return any(function (pat) return match_gitignore(filepath, pat) end, extra_ignore) + return opts.extra_ignore, function (_) return false end end end)() - - local is_os_ignored = (function () - if not use_os_ignore then return false end - local os_ignore = require('esqueleto.constants').ignored_files - return any(function (pat) return match_gitignore(filepath, pat) end, os_ignore) - end)() - - return is_user_ignored or is_os_ignored -end - -M.getunignoredtemplates = function(pattern, opts) - local templates = {} - local alldirectories = opts.directories - local extra_ignore = opts.extra_ignore - local use_os_ignore = opts.use_os_ignore + local alldirectories = vim.tbl_map(function (f) + return vim.fn.fnamemodify(f, ':p') + end, opts.directories) -- Count directories that contain templates for pattern local ndirs = 0 for _, directory in pairs(alldirectories) do - directory = vim.fn.fnamemodify(directory, ':p') -- expand path ndirs = ndirs + vim.fn.isdirectory(directory .. pattern .. '/') end -- Get templates for pattern for _, directory in ipairs(alldirectories) do - directory = vim.fn.fnamemodify(directory, ':p') -- expand path - if vim.fn.isdirectory(directory .. pattern .. '/') == 1 then - for filepath in vim.fs.dir(directory .. pattern .. '/') do - filepath = directory .. pattern .. "/" .. filepath - local ignored = isignored(filepath, extra_ignore, use_os_ignore) + local pattern_dir = directory .. pattern .. '/' + local exists_dir = vim.fn.isdirectory(pattern_dir) == 1 + if exists_dir then + local os_ignored_files = use_os_ignore and list_os_ignored_files(pattern_dir) or {} + local user_ignored_files = list_user_ignored_files(pattern_dir, extra_ignore_pats) + for basename in vim.fs.dir(pattern_dir) do + local filepath = vim.fs.normalize(pattern_dir .. basename) + local ignored = extra_ignore_func(filepath) or vim.tbl_contains(os_ignored_files, filepath) or vim.tbl_contains(user_ignored_files, filepath) if not ignored then local name = vim.fs.basename(filepath) if ndirs > 1 then From 875f37e2c1ae4014bfd6ede82caa963f909ba91b Mon Sep 17 00:00:00 2001 From: Futar Date: Sat, 30 Sep 2023 07:44:00 +0100 Subject: [PATCH 10/21] chore: cleanup --- lua/esqueleto/utils.lua | 52 +++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index b1b9619..f6de28a 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -36,29 +36,38 @@ M.gettemplates = function(pattern, alldirectories) return templates end -M.getunignoredtemplates = function(pattern, opts) - local list_ignored = function (dir, ignored_pats) - return vim.tbl_flatten(vim.tbl_map(function (pat) - return vim.fn.globpath(dir, pat, true, true, true) - end, ignored_pats)) - end - - local list_os_ignored_files = function (dir) - return list_ignored(dir, require('esqueleto.constants').ignored_patterns) - end - - local list_user_ignored_files = list_ignored +-- List ignored files under a directory, given a list of glob patterns +local listignored = function(dir, ignored_pats) + return vim.tbl_flatten(vim.tbl_map(function(pat) + return vim.fn.globpath(dir, pat, true, true, true) + end, ignored_pats)) +end - local templates = {} - local use_os_ignore = opts.use_os_ignore - local extra_ignore_pats, extra_ignore_func = (function () - if type(opts.extra_ignore) == 'function' then - return {}, opts.extra_ignore +-- Returns a ignore checker +local getignorechecker = function(opts) + local os_ignore_pats = opts.use_os_ignore and require('esqueleto.constants').ignored_patterns or {} + local extra = opts.extra_ignore + local extra_ignore_pats, extra_ignore_func = (function() + if type(extra) == 'function' then + return {}, extra else - return opts.extra_ignore, function (_) return false end + assert(type(extra) == 'table') + return extra, function(_) return false end end end)() - local alldirectories = vim.tbl_map(function (f) + + return function(filepath) + local dir = vim.fn.fnamemodify(filepath, ':p:h') + return extra_ignore_func(dir) or vim.tbl_contains(listignored(dir, os_ignore_pats), filepath) + or vim.tbl_contains(listignored(dir, extra_ignore_pats), filepath) + end +end + +M.getunignoredtemplates = function(pattern, opts) + local templates = {} + local isignored = getignorechecker(opts) + + local alldirectories = vim.tbl_map(function(f) return vim.fn.fnamemodify(f, ':p') end, opts.directories) @@ -73,12 +82,9 @@ M.getunignoredtemplates = function(pattern, opts) local pattern_dir = directory .. pattern .. '/' local exists_dir = vim.fn.isdirectory(pattern_dir) == 1 if exists_dir then - local os_ignored_files = use_os_ignore and list_os_ignored_files(pattern_dir) or {} - local user_ignored_files = list_user_ignored_files(pattern_dir, extra_ignore_pats) for basename in vim.fs.dir(pattern_dir) do local filepath = vim.fs.normalize(pattern_dir .. basename) - local ignored = extra_ignore_func(filepath) or vim.tbl_contains(os_ignored_files, filepath) or vim.tbl_contains(user_ignored_files, filepath) - if not ignored then + if not isignored(filepath) then local name = vim.fs.basename(filepath) if ndirs > 1 then name = vim.fn.simplify(directory) .. " :: " .. name From 5cb6d8115d468065b648db6a59853eca2e1e2e15 Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 08:47:05 +0100 Subject: [PATCH 11/21] feat(qol): new option to ignore certain files TODO: update README and doc --- lua/esqueleto/config.lua | 2 ++ lua/esqueleto/utils.lua | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lua/esqueleto/config.lua b/lua/esqueleto/config.lua index 16b37d9..2b4b265 100644 --- a/lua/esqueleto/config.lua +++ b/lua/esqueleto/config.lua @@ -4,6 +4,7 @@ M.default_config = { autouse = true, directories = { vim.fn.stdpath("config") .. "/skeletons" }, patterns = {}, + ignore = function (f) return vim.fn.fnamemodify(f, ':t') == '.DS_Store' end, } M.updateconfig = function(config) @@ -15,6 +16,7 @@ M.updateconfig = function(config) autouse = { config.autouse, 'boolean' }, directories = { config.directories, 'table' }, patterns = { config.patterns, 'table' }, + ignore = { config.ignore, 'function' }, }) return config diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index 3afd639..8bdd23b 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -2,6 +2,10 @@ local M = {} _G.esqueleto_inserted = {} +M.isignored = function(ignore, filepath) + return ignore(filepath) +end + M.writetemplate = function(file) if file ~= nil then vim.cmd("0r " .. file) @@ -36,6 +40,36 @@ M.gettemplates = function(pattern, alldirectories) return templates end +M.getunignoredtemplates = function(pattern, alldirectories, ignore) + local templates = {} + + -- Count directories that contain templates for pattern + local ndirs = 0 + for _, directory in pairs(alldirectories) do + directory = vim.fn.fnamemodify(directory, ':p') -- expand path + ndirs = ndirs + vim.fn.isdirectory(directory .. pattern .. '/') + end + + -- Get templates for pattern + for _, directory in ipairs(alldirectories) do + directory = vim.fn.fnamemodify(directory, ':p') -- expand path + if vim.fn.isdirectory(directory .. pattern .. '/') == 1 then + for filepath in vim.fs.dir(directory .. pattern .. '/') do + filepath = directory .. pattern .. "/" .. filepath + if not M.isignored(ignore, filepath) then + local name = vim.fs.basename(filepath) + if ndirs > 1 then + name = vim.fn.simplify(directory) .. " :: " .. name + end + templates[name] = filepath + end + end + end + end + + return templates +end + M.selecttemplate = function(templates, opts) -- Check if templates exist if vim.tbl_isempty(templates) then @@ -83,7 +117,7 @@ M.inserttemplate = function(opts) end -- Get templates for selected pattern - local templates = M.gettemplates(pattern, opts.directories) + local templates = M.getunignoredtemplates(pattern, opts.directories, opts.ignore) -- Pop-up selection UI M.selecttemplate(templates, opts) From b59e413d3720577b2e88fe04b70739057ed02b8d Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 20:49:27 +0100 Subject: [PATCH 12/21] feat(qol): add some common OS files to ignore --- lua/esqueleto/constants.lua | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 lua/esqueleto/constants.lua diff --git a/lua/esqueleto/constants.lua b/lua/esqueleto/constants.lua new file mode 100644 index 0000000..c1f1dd6 --- /dev/null +++ b/lua/esqueleto/constants.lua @@ -0,0 +1,7 @@ +local M = {} + +-- OS-specific ignoring files, from `https://www.toptal.com/developers/gitignore/api/windows,macos,linux` +-- Index: Thu Sep 28 20:45:56 BST 2023 +M.ignored_files = { '*~', '.fuse_hidden*', '.directory', '.Trash-*', '.nfs*', '.DS_Store', '.AppleDouble', '.LSOverride', 'Icon', '._*', '.DocumentRevisions-V100', '.fseventsd', '.Spotlight-V100', '.TemporaryItems', '.Trashes', '.VolumeIcon.icns', '.com.apple.timemachine.donotpresent', '.AppleDB', '.AppleDesktop', 'Network Trash Folder', 'Temporary Items', '.apdisk', '*.icloud', 'Thumbs.db', 'Thumbs.db:encryptable', 'ehthumbs.db', 'ehthumbs_vista.db', '*.stackdump', '[Dd]esktop.ini', '$RECYCLE.BIN/', '*.cab', '*.msi', '*.msix', '*.msm', '*.msp', '*.lnk' } + +return M From 8fdb3aa9b916566139667e6df31f3c88c38d80b6 Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 21:30:28 +0100 Subject: [PATCH 13/21] refactor(qol): revise user options --- lua/esqueleto/config.lua | 6 +++-- lua/esqueleto/utils.lua | 51 ++++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/lua/esqueleto/config.lua b/lua/esqueleto/config.lua index 2b4b265..0f45f7d 100644 --- a/lua/esqueleto/config.lua +++ b/lua/esqueleto/config.lua @@ -4,7 +4,8 @@ M.default_config = { autouse = true, directories = { vim.fn.stdpath("config") .. "/skeletons" }, patterns = {}, - ignore = function (f) return vim.fn.fnamemodify(f, ':t') == '.DS_Store' end, + use_os_ignore = true, + extra_ignore = {}, } M.updateconfig = function(config) @@ -16,7 +17,8 @@ M.updateconfig = function(config) autouse = { config.autouse, 'boolean' }, directories = { config.directories, 'table' }, patterns = { config.patterns, 'table' }, - ignore = { config.ignore, 'function' }, + use_os_ignore = { config.use_os_ignore, 'boolean' }, + extra_ignore = { config.extra_ignore, { 'table', 'function' } }, }) return config diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index 8bdd23b..5865540 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -2,10 +2,6 @@ local M = {} _G.esqueleto_inserted = {} -M.isignored = function(ignore, filepath) - return ignore(filepath) -end - M.writetemplate = function(file) if file ~= nil then vim.cmd("0r " .. file) @@ -40,8 +36,48 @@ M.gettemplates = function(pattern, alldirectories) return templates end -M.getunignoredtemplates = function(pattern, alldirectories, ignore) +local any = function (f, t) + for _, e in pairs(t) do + if f(e) then + return true + end + end + + return false +end + +-- Determine if a file matches a gitignore glob pattern +-- by converting to regex, then vim.regex API. +local match_gitignore = function (filepath, gitignore_pattern) + local regpat = vim.fn.glob2regpat(gitignore_pattern) -- ^$ automatically added + return vim.regex(regpat):match_str(filepath) ~= nil +end + +-- Determine if a file should be ignored, +-- according to user's choice +local isignored = function (filepath, extra_ignore, use_os_ignore) + local is_user_ignored = (function () + if type(extra_ignore) == 'function' then + return extra_ignore(filepath) + else + return any(function (pat) return match_gitignore(filepath, pat) end, extra_ignore) + end + end)() + + local is_os_ignored = (function () + if not use_os_ignore then return false end + local os_ignore = require('esqueleto.constants').ignored_files + return any(function (pat) return match_gitignore(filepath, pat) end, os_ignore) + end)() + + return is_user_ignored or is_os_ignored +end + +M.getunignoredtemplates = function(pattern, opts) local templates = {} + local alldirectories = opts.directories + local extra_ignore = opts.extra_ignore + local use_os_ignore = opts.use_os_ignore -- Count directories that contain templates for pattern local ndirs = 0 @@ -56,7 +92,8 @@ M.getunignoredtemplates = function(pattern, alldirectories, ignore) if vim.fn.isdirectory(directory .. pattern .. '/') == 1 then for filepath in vim.fs.dir(directory .. pattern .. '/') do filepath = directory .. pattern .. "/" .. filepath - if not M.isignored(ignore, filepath) then + local ignored = isignored(filepath, extra_ignore, use_os_ignore) + if not ignored then local name = vim.fs.basename(filepath) if ndirs > 1 then name = vim.fn.simplify(directory) .. " :: " .. name @@ -117,7 +154,7 @@ M.inserttemplate = function(opts) end -- Get templates for selected pattern - local templates = M.getunignoredtemplates(pattern, opts.directories, opts.ignore) + local templates = M.getunignoredtemplates(pattern, opts) -- Pop-up selection UI M.selecttemplate(templates, opts) From 5310f11c11a1d1738cbfe09e953127fe77cf3308 Mon Sep 17 00:00:00 2001 From: Futar Date: Thu, 28 Sep 2023 22:44:07 +0100 Subject: [PATCH 14/21] fix(qol): partially fix `match_gitignore` --- lua/esqueleto/utils.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index 5865540..a3e94dd 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -49,8 +49,15 @@ end -- Determine if a file matches a gitignore glob pattern -- by converting to regex, then vim.regex API. local match_gitignore = function (filepath, gitignore_pattern) - local regpat = vim.fn.glob2regpat(gitignore_pattern) -- ^$ automatically added - return vim.regex(regpat):match_str(filepath) ~= nil + local regpat = vim.fn.glob2regpat(gitignore_pattern):sub(2) -- manually remove ^; hackish + local start, finish = vim.regex(regpat):match_str(filepath) + local res = (function () + if start == nil or finish == nil then return false end + if start == finish then return false end -- empty match, won't do + return finish == #filepath + end)() + + return res end -- Determine if a file should be ignored, From 577166fd5ab7c3f994d5d92a1fa62b36d61d33b0 Mon Sep 17 00:00:00 2001 From: Futar Date: Fri, 29 Sep 2023 15:41:44 +0100 Subject: [PATCH 15/21] refactor(qol): use more sensible approach for ignoring patterns Additionally: - Renamed "ignore patterns" constant --- lua/esqueleto/constants.lua | 2 +- lua/esqueleto/utils.lua | 74 +++++++++++++------------------------ 2 files changed, 27 insertions(+), 49 deletions(-) diff --git a/lua/esqueleto/constants.lua b/lua/esqueleto/constants.lua index c1f1dd6..e33a4c6 100644 --- a/lua/esqueleto/constants.lua +++ b/lua/esqueleto/constants.lua @@ -2,6 +2,6 @@ local M = {} -- OS-specific ignoring files, from `https://www.toptal.com/developers/gitignore/api/windows,macos,linux` -- Index: Thu Sep 28 20:45:56 BST 2023 -M.ignored_files = { '*~', '.fuse_hidden*', '.directory', '.Trash-*', '.nfs*', '.DS_Store', '.AppleDouble', '.LSOverride', 'Icon', '._*', '.DocumentRevisions-V100', '.fseventsd', '.Spotlight-V100', '.TemporaryItems', '.Trashes', '.VolumeIcon.icns', '.com.apple.timemachine.donotpresent', '.AppleDB', '.AppleDesktop', 'Network Trash Folder', 'Temporary Items', '.apdisk', '*.icloud', 'Thumbs.db', 'Thumbs.db:encryptable', 'ehthumbs.db', 'ehthumbs_vista.db', '*.stackdump', '[Dd]esktop.ini', '$RECYCLE.BIN/', '*.cab', '*.msi', '*.msix', '*.msm', '*.msp', '*.lnk' } +M.ignored_patterns = { '*~', '.fuse_hidden*', '.directory', '.Trash-*', '.nfs*', '.DS_Store', '.AppleDouble', '.LSOverride', 'Icon', '._*', '.DocumentRevisions-V100', '.fseventsd', '.Spotlight-V100', '.TemporaryItems', '.Trashes', '.VolumeIcon.icns', '.com.apple.timemachine.donotpresent', '.AppleDB', '.AppleDesktop', 'Network Trash Folder', 'Temporary Items', '.apdisk', '*.icloud', 'Thumbs.db', 'Thumbs.db:encryptable', 'ehthumbs.db', 'ehthumbs_vista.db', '*.stackdump', '[Dd]esktop.ini', '$RECYCLE.BIN/', '*.cab', '*.msi', '*.msix', '*.msm', '*.msp', '*.lnk' } return M diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index a3e94dd..b1b9619 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -36,70 +36,48 @@ M.gettemplates = function(pattern, alldirectories) return templates end -local any = function (f, t) - for _, e in pairs(t) do - if f(e) then - return true - end +M.getunignoredtemplates = function(pattern, opts) + local list_ignored = function (dir, ignored_pats) + return vim.tbl_flatten(vim.tbl_map(function (pat) + return vim.fn.globpath(dir, pat, true, true, true) + end, ignored_pats)) end - return false -end + local list_os_ignored_files = function (dir) + return list_ignored(dir, require('esqueleto.constants').ignored_patterns) + end --- Determine if a file matches a gitignore glob pattern --- by converting to regex, then vim.regex API. -local match_gitignore = function (filepath, gitignore_pattern) - local regpat = vim.fn.glob2regpat(gitignore_pattern):sub(2) -- manually remove ^; hackish - local start, finish = vim.regex(regpat):match_str(filepath) - local res = (function () - if start == nil or finish == nil then return false end - if start == finish then return false end -- empty match, won't do - return finish == #filepath - end)() + local list_user_ignored_files = list_ignored - return res -end - --- Determine if a file should be ignored, --- according to user's choice -local isignored = function (filepath, extra_ignore, use_os_ignore) - local is_user_ignored = (function () - if type(extra_ignore) == 'function' then - return extra_ignore(filepath) + local templates = {} + local use_os_ignore = opts.use_os_ignore + local extra_ignore_pats, extra_ignore_func = (function () + if type(opts.extra_ignore) == 'function' then + return {}, opts.extra_ignore else - return any(function (pat) return match_gitignore(filepath, pat) end, extra_ignore) + return opts.extra_ignore, function (_) return false end end end)() - - local is_os_ignored = (function () - if not use_os_ignore then return false end - local os_ignore = require('esqueleto.constants').ignored_files - return any(function (pat) return match_gitignore(filepath, pat) end, os_ignore) - end)() - - return is_user_ignored or is_os_ignored -end - -M.getunignoredtemplates = function(pattern, opts) - local templates = {} - local alldirectories = opts.directories - local extra_ignore = opts.extra_ignore - local use_os_ignore = opts.use_os_ignore + local alldirectories = vim.tbl_map(function (f) + return vim.fn.fnamemodify(f, ':p') + end, opts.directories) -- Count directories that contain templates for pattern local ndirs = 0 for _, directory in pairs(alldirectories) do - directory = vim.fn.fnamemodify(directory, ':p') -- expand path ndirs = ndirs + vim.fn.isdirectory(directory .. pattern .. '/') end -- Get templates for pattern for _, directory in ipairs(alldirectories) do - directory = vim.fn.fnamemodify(directory, ':p') -- expand path - if vim.fn.isdirectory(directory .. pattern .. '/') == 1 then - for filepath in vim.fs.dir(directory .. pattern .. '/') do - filepath = directory .. pattern .. "/" .. filepath - local ignored = isignored(filepath, extra_ignore, use_os_ignore) + local pattern_dir = directory .. pattern .. '/' + local exists_dir = vim.fn.isdirectory(pattern_dir) == 1 + if exists_dir then + local os_ignored_files = use_os_ignore and list_os_ignored_files(pattern_dir) or {} + local user_ignored_files = list_user_ignored_files(pattern_dir, extra_ignore_pats) + for basename in vim.fs.dir(pattern_dir) do + local filepath = vim.fs.normalize(pattern_dir .. basename) + local ignored = extra_ignore_func(filepath) or vim.tbl_contains(os_ignored_files, filepath) or vim.tbl_contains(user_ignored_files, filepath) if not ignored then local name = vim.fs.basename(filepath) if ndirs > 1 then From 3266cadedb8decb56d07eaf3c7a7c26ccade772c Mon Sep 17 00:00:00 2001 From: Futar Date: Sat, 30 Sep 2023 07:44:00 +0100 Subject: [PATCH 16/21] chore(qol): cleanup --- lua/esqueleto/utils.lua | 52 +++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index b1b9619..f6de28a 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -36,29 +36,38 @@ M.gettemplates = function(pattern, alldirectories) return templates end -M.getunignoredtemplates = function(pattern, opts) - local list_ignored = function (dir, ignored_pats) - return vim.tbl_flatten(vim.tbl_map(function (pat) - return vim.fn.globpath(dir, pat, true, true, true) - end, ignored_pats)) - end - - local list_os_ignored_files = function (dir) - return list_ignored(dir, require('esqueleto.constants').ignored_patterns) - end - - local list_user_ignored_files = list_ignored +-- List ignored files under a directory, given a list of glob patterns +local listignored = function(dir, ignored_pats) + return vim.tbl_flatten(vim.tbl_map(function(pat) + return vim.fn.globpath(dir, pat, true, true, true) + end, ignored_pats)) +end - local templates = {} - local use_os_ignore = opts.use_os_ignore - local extra_ignore_pats, extra_ignore_func = (function () - if type(opts.extra_ignore) == 'function' then - return {}, opts.extra_ignore +-- Returns a ignore checker +local getignorechecker = function(opts) + local os_ignore_pats = opts.use_os_ignore and require('esqueleto.constants').ignored_patterns or {} + local extra = opts.extra_ignore + local extra_ignore_pats, extra_ignore_func = (function() + if type(extra) == 'function' then + return {}, extra else - return opts.extra_ignore, function (_) return false end + assert(type(extra) == 'table') + return extra, function(_) return false end end end)() - local alldirectories = vim.tbl_map(function (f) + + return function(filepath) + local dir = vim.fn.fnamemodify(filepath, ':p:h') + return extra_ignore_func(dir) or vim.tbl_contains(listignored(dir, os_ignore_pats), filepath) + or vim.tbl_contains(listignored(dir, extra_ignore_pats), filepath) + end +end + +M.getunignoredtemplates = function(pattern, opts) + local templates = {} + local isignored = getignorechecker(opts) + + local alldirectories = vim.tbl_map(function(f) return vim.fn.fnamemodify(f, ':p') end, opts.directories) @@ -73,12 +82,9 @@ M.getunignoredtemplates = function(pattern, opts) local pattern_dir = directory .. pattern .. '/' local exists_dir = vim.fn.isdirectory(pattern_dir) == 1 if exists_dir then - local os_ignored_files = use_os_ignore and list_os_ignored_files(pattern_dir) or {} - local user_ignored_files = list_user_ignored_files(pattern_dir, extra_ignore_pats) for basename in vim.fs.dir(pattern_dir) do local filepath = vim.fs.normalize(pattern_dir .. basename) - local ignored = extra_ignore_func(filepath) or vim.tbl_contains(os_ignored_files, filepath) or vim.tbl_contains(user_ignored_files, filepath) - if not ignored then + if not isignored(filepath) then local name = vim.fs.basename(filepath) if ndirs > 1 then name = vim.fn.simplify(directory) .. " :: " .. name From 124ffbdbcc4fd3c8d20db28bf91b609855cb8bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Vigil=20V=C3=A1squez?= Date: Sat, 30 Sep 2023 13:49:21 -0300 Subject: [PATCH 17/21] refactor(qol): cleanup templates ignoring behavior --- lua/esqueleto/config.lua | 11 ++++++--- lua/esqueleto/constants.lua | 42 +++++++++++++++++++++++++++++-- lua/esqueleto/utils.lua | 49 +++++++++---------------------------- 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/lua/esqueleto/config.lua b/lua/esqueleto/config.lua index 0f45f7d..b63c8b7 100644 --- a/lua/esqueleto/config.lua +++ b/lua/esqueleto/config.lua @@ -4,8 +4,10 @@ M.default_config = { autouse = true, directories = { vim.fn.stdpath("config") .. "/skeletons" }, patterns = {}, - use_os_ignore = true, - extra_ignore = {}, + advanced = { + ignored = {}, + ignore_os_files = true, + } } M.updateconfig = function(config) @@ -17,8 +19,9 @@ M.updateconfig = function(config) autouse = { config.autouse, 'boolean' }, directories = { config.directories, 'table' }, patterns = { config.patterns, 'table' }, - use_os_ignore = { config.use_os_ignore, 'boolean' }, - extra_ignore = { config.extra_ignore, { 'table', 'function' } }, + advanced = { config.advanced, 'table' }, + ["advanced.ignored"] = { config.advanced.ignored, { 'table', 'function' } }, + ["advanced.ignore_os_files"] = { config.advanced.ignore_os_files, 'boolean' }, }) return config diff --git a/lua/esqueleto/constants.lua b/lua/esqueleto/constants.lua index e33a4c6..97514a2 100644 --- a/lua/esqueleto/constants.lua +++ b/lua/esqueleto/constants.lua @@ -1,7 +1,45 @@ local M = {} --- OS-specific ignoring files, from `https://www.toptal.com/developers/gitignore/api/windows,macos,linux` +-- OS-specific ignoring files, obtained from gitignore.io +-- `https://www.toptal.com/developers/gitignore/api/windows,macos,linux` -- Index: Thu Sep 28 20:45:56 BST 2023 -M.ignored_patterns = { '*~', '.fuse_hidden*', '.directory', '.Trash-*', '.nfs*', '.DS_Store', '.AppleDouble', '.LSOverride', 'Icon', '._*', '.DocumentRevisions-V100', '.fseventsd', '.Spotlight-V100', '.TemporaryItems', '.Trashes', '.VolumeIcon.icns', '.com.apple.timemachine.donotpresent', '.AppleDB', '.AppleDesktop', 'Network Trash Folder', 'Temporary Items', '.apdisk', '*.icloud', 'Thumbs.db', 'Thumbs.db:encryptable', 'ehthumbs.db', 'ehthumbs_vista.db', '*.stackdump', '[Dd]esktop.ini', '$RECYCLE.BIN/', '*.cab', '*.msi', '*.msix', '*.msm', '*.msp', '*.lnk' } +M.ignored_os_patterns = { + "*~", + ".fuse_hidden*", + ".directory", + ".Trash-*", + ".nfs*", + ".DS_Store", + ".AppleDouble", + ".LSOverride", + "Icon", + "._*", + ".DocumentRevisions-V100", + ".fseventsd", + ".Spotlight-V100", + ".TemporaryItems", + ".Trashes", + ".VolumeIcon.icns", + ".com.apple.timemachine.donotpresent", + ".AppleDB", + ".AppleDesktop", + "Network Trash Folder", + "Temporary Items", + ".apdisk", + "*.icloud", + "Thumbs.db", + "Thumbs.db:encryptable", + "ehthumbs.db", + "ehthumbs_vista.db", + "*.stackdump", + "[Dd]esktop.ini", + "$RECYCLE.BIN/", + "*.cab", + "*.msi", + "*.msix", + "*.msm", + "*.msp", + "*.lnk", +} return M diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index f6de28a..fe2570b 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -2,51 +2,24 @@ local M = {} _G.esqueleto_inserted = {} +-- Write template contents to buffer M.writetemplate = function(file) if file ~= nil then vim.cmd("0r " .. file) end end -M.gettemplates = function(pattern, alldirectories) - local templates = {} - - -- Count directories that contain templates for pattern - local ndirs = 0 - for _, directory in pairs(alldirectories) do - directory = vim.fn.fnamemodify(directory, ':p') -- expand path - ndirs = ndirs + vim.fn.isdirectory(directory .. pattern .. '/') - end - - -- Get templates for pattern - for _, directory in ipairs(alldirectories) do - directory = vim.fn.fnamemodify(directory, ':p') -- expand path - if vim.fn.isdirectory(directory .. pattern .. '/') == 1 then - for filepath in vim.fs.dir(directory .. pattern .. '/') do - filepath = directory .. pattern .. "/" .. filepath - local name = vim.fs.basename(filepath) - if ndirs > 1 then - name = vim.fn.simplify(directory) .. " :: " .. name - end - templates[name] = filepath - end - end - end - - return templates -end - -- List ignored files under a directory, given a list of glob patterns -local listignored = function(dir, ignored_pats) - return vim.tbl_flatten(vim.tbl_map(function(pat) - return vim.fn.globpath(dir, pat, true, true, true) - end, ignored_pats)) +local listignored = function(dir, ignored_patterns) + return vim.tbl_flatten(vim.tbl_map(function(patterns) + return vim.fn.globpath(dir, patterns, true, true, true) + end, ignored_patterns)) end -- Returns a ignore checker local getignorechecker = function(opts) - local os_ignore_pats = opts.use_os_ignore and require('esqueleto.constants').ignored_patterns or {} - local extra = opts.extra_ignore + local os_ignore_pats = opts.advanced.ignore_os_files and require('esqueleto.constants').ignored_os_patterns or {} + local extra = opts.advanced.ignored local extra_ignore_pats, extra_ignore_func = (function() if type(extra) == 'function' then return {}, extra @@ -58,12 +31,13 @@ local getignorechecker = function(opts) return function(filepath) local dir = vim.fn.fnamemodify(filepath, ':p:h') - return extra_ignore_func(dir) or vim.tbl_contains(listignored(dir, os_ignore_pats), filepath) + return extra_ignore_func(dir) + or vim.tbl_contains(listignored(dir, os_ignore_pats), filepath) or vim.tbl_contains(listignored(dir, extra_ignore_pats), filepath) end end -M.getunignoredtemplates = function(pattern, opts) +M.gettemplates = function(pattern, opts) local templates = {} local isignored = getignorechecker(opts) @@ -84,6 +58,7 @@ M.getunignoredtemplates = function(pattern, opts) if exists_dir then for basename in vim.fs.dir(pattern_dir) do local filepath = vim.fs.normalize(pattern_dir .. basename) + -- Check if pattern is ignored if not isignored(filepath) then local name = vim.fs.basename(filepath) if ndirs > 1 then @@ -145,7 +120,7 @@ M.inserttemplate = function(opts) end -- Get templates for selected pattern - local templates = M.getunignoredtemplates(pattern, opts) + local templates = M.gettemplates(pattern, opts) -- Pop-up selection UI M.selecttemplate(templates, opts) From 725de63ce4905329eb470710db3493c3737d3b4e Mon Sep 17 00:00:00 2001 From: Futar Date: Sat, 30 Sep 2023 18:28:43 +0100 Subject: [PATCH 18/21] ditto --- lua/esqueleto/config.lua | 10 ------ lua/esqueleto/constants.lua | 6 ---- lua/esqueleto/utils.lua | 66 ------------------------------------- 3 files changed, 82 deletions(-) diff --git a/lua/esqueleto/config.lua b/lua/esqueleto/config.lua index d8d7f45..b63c8b7 100644 --- a/lua/esqueleto/config.lua +++ b/lua/esqueleto/config.lua @@ -4,15 +4,10 @@ M.default_config = { autouse = true, directories = { vim.fn.stdpath("config") .. "/skeletons" }, patterns = {}, -<<<<<<< HEAD - use_os_ignore = true, - extra_ignore = {}, -======= advanced = { ignored = {}, ignore_os_files = true, } ->>>>>>> origin/main } M.updateconfig = function(config) @@ -24,14 +19,9 @@ M.updateconfig = function(config) autouse = { config.autouse, 'boolean' }, directories = { config.directories, 'table' }, patterns = { config.patterns, 'table' }, -<<<<<<< HEAD - use_os_ignore = { config.use_os_ignore, 'boolean' }, - extra_ignore = { config.extra_ignore, { 'table', 'function' } }, -======= advanced = { config.advanced, 'table' }, ["advanced.ignored"] = { config.advanced.ignored, { 'table', 'function' } }, ["advanced.ignore_os_files"] = { config.advanced.ignore_os_files, 'boolean' }, ->>>>>>> origin/main }) return config diff --git a/lua/esqueleto/constants.lua b/lua/esqueleto/constants.lua index 911a3b1..97514a2 100644 --- a/lua/esqueleto/constants.lua +++ b/lua/esqueleto/constants.lua @@ -1,10 +1,5 @@ local M = {} -<<<<<<< HEAD --- OS-specific ignoring files, from `https://www.toptal.com/developers/gitignore/api/windows,macos,linux` --- Index: Thu Sep 28 20:45:56 BST 2023 -M.ignored_patterns = { '*~', '.fuse_hidden*', '.directory', '.Trash-*', '.nfs*', '.DS_Store', '.AppleDouble', '.LSOverride', 'Icon', '._*', '.DocumentRevisions-V100', '.fseventsd', '.Spotlight-V100', '.TemporaryItems', '.Trashes', '.VolumeIcon.icns', '.com.apple.timemachine.donotpresent', '.AppleDB', '.AppleDesktop', 'Network Trash Folder', 'Temporary Items', '.apdisk', '*.icloud', 'Thumbs.db', 'Thumbs.db:encryptable', 'ehthumbs.db', 'ehthumbs_vista.db', '*.stackdump', '[Dd]esktop.ini', '$RECYCLE.BIN/', '*.cab', '*.msi', '*.msix', '*.msm', '*.msp', '*.lnk' } -======= -- OS-specific ignoring files, obtained from gitignore.io -- `https://www.toptal.com/developers/gitignore/api/windows,macos,linux` -- Index: Thu Sep 28 20:45:56 BST 2023 @@ -46,6 +41,5 @@ M.ignored_os_patterns = { "*.msp", "*.lnk", } ->>>>>>> origin/main return M diff --git a/lua/esqueleto/utils.lua b/lua/esqueleto/utils.lua index 995a577..fe2570b 100644 --- a/lua/esqueleto/utils.lua +++ b/lua/esqueleto/utils.lua @@ -73,68 +73,6 @@ M.gettemplates = function(pattern, opts) return templates end --- List ignored files under a directory, given a list of glob patterns -local listignored = function(dir, ignored_pats) - return vim.tbl_flatten(vim.tbl_map(function(pat) - return vim.fn.globpath(dir, pat, true, true, true) - end, ignored_pats)) -end - --- Returns a ignore checker -local getignorechecker = function(opts) - local os_ignore_pats = opts.use_os_ignore and require('esqueleto.constants').ignored_patterns or {} - local extra = opts.extra_ignore - local extra_ignore_pats, extra_ignore_func = (function() - if type(extra) == 'function' then - return {}, extra - else - assert(type(extra) == 'table') - return extra, function(_) return false end - end - end)() - - return function(filepath) - local dir = vim.fn.fnamemodify(filepath, ':p:h') - return extra_ignore_func(dir) or vim.tbl_contains(listignored(dir, os_ignore_pats), filepath) - or vim.tbl_contains(listignored(dir, extra_ignore_pats), filepath) - end -end - -M.getunignoredtemplates = function(pattern, opts) - local templates = {} - local isignored = getignorechecker(opts) - - local alldirectories = vim.tbl_map(function(f) - return vim.fn.fnamemodify(f, ':p') - end, opts.directories) - - -- Count directories that contain templates for pattern - local ndirs = 0 - for _, directory in pairs(alldirectories) do - ndirs = ndirs + vim.fn.isdirectory(directory .. pattern .. '/') - end - - -- Get templates for pattern - for _, directory in ipairs(alldirectories) do - local pattern_dir = directory .. pattern .. '/' - local exists_dir = vim.fn.isdirectory(pattern_dir) == 1 - if exists_dir then - for basename in vim.fs.dir(pattern_dir) do - local filepath = vim.fs.normalize(pattern_dir .. basename) - if not isignored(filepath) then - local name = vim.fs.basename(filepath) - if ndirs > 1 then - name = vim.fn.simplify(directory) .. " :: " .. name - end - templates[name] = filepath - end - end - end - end - - return templates -end - M.selecttemplate = function(templates, opts) -- Check if templates exist if vim.tbl_isempty(templates) then @@ -182,11 +120,7 @@ M.inserttemplate = function(opts) end -- Get templates for selected pattern -<<<<<<< HEAD - local templates = M.getunignoredtemplates(pattern, opts) -======= local templates = M.gettemplates(pattern, opts) ->>>>>>> origin/main -- Pop-up selection UI M.selecttemplate(templates, opts) From 8089ead652b0a23004c216a1da46be162520cd0e Mon Sep 17 00:00:00 2001 From: Futar Date: Sat, 30 Sep 2023 18:31:06 +0100 Subject: [PATCH 19/21] docs(advanced): add advanced options to readme --- README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b36a39b..208ed23 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,16 @@ require("esqueleto").setup( patterns = { "README.md", "python" }, -- whether to auto-use a template if it's the only one for a pattern - autouse = true + autouse = true, + + advanced = { + -- List of files glob patterns to ignore + ignored = {}, + + -- Ignore OS files like .DS_Store + -- Exhaustive list: https://www.toptal.com/developers/gitignore/api/windows,macos,linux + ignore_os_files = true, + }, } ) ``` @@ -63,7 +72,11 @@ The default options of `esqueleto` are { directories = { vim.fn.stdpath("config") .. "/skeletons" }, patterns = { }, - autouse = true + autouse = true, + advanced = { + ignored = {}, + ignore_os_files = true, + } } ~~~ From 1e5547411b9852b5e1298e62d5cd4937a1fc8444 Mon Sep 17 00:00:00 2001 From: Futar Date: Sat, 30 Sep 2023 19:41:41 +0100 Subject: [PATCH 20/21] docs(advanced): improve `ignored` option desc --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 208ed23..61196d2 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ require("esqueleto").setup( advanced = { -- List of files glob patterns to ignore + -- Or alternatively, a function that determines if a file should be ignored ignored = {}, -- Ignore OS files like .DS_Store From 87b437b2ba63c7cbad55995f3f2d5c9a98304165 Mon Sep 17 00:00:00 2001 From: Futar Date: Sat, 30 Sep 2023 21:09:50 +0100 Subject: [PATCH 21/21] docs(advanced): update docstring --- doc/esqueleto.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/esqueleto.txt b/doc/esqueleto.txt index d3a77ad..6d26616 100644 --- a/doc/esqueleto.txt +++ b/doc/esqueleto.txt @@ -54,6 +54,12 @@ First, |esqueleto| setup in the `init.lua` file is as follows: > -- File type 'python', }, + + -- Advanced options + advanced = { + ignore_os_files = true, + ignore = {} + }, }) < Second (and based in the setup showcased above), the following step involves @@ -119,6 +125,7 @@ setup({patterns}, {directory}) { directories = {vim.fn.stdpath("config") .. "/skeletons"}, patterns = { }, + advanced = { ignore = {}, ignore_os_files = true }, } ) < @@ -127,6 +134,15 @@ setup({patterns}, {directory}) • {patterns} (table) File names or patterns to match • {directory} (string) An absolute or relative path to the directory with templates. + • {advanced} (table) Advanced options, including: + • {ignore} (table|function) List of glob patterns of + files to be ignored; alternatively, a + predicate that determines if a file + should be ignored, given its full filepath. + • {ignore_os_files} (boolean) Whether to ignore OS files, + such as `.DS_Store`, `Desktop.ini`. + For an exhaustive list, see + `https://www.toptal.com/developers/gitignore/api/windows,macos,linux` ============================================================================== *ex-commands*