diff options
| -rw-r--r-- | README.md | 28 | ||||
| -rw-r--r-- | doc/muwiki.txt | 134 | ||||
| -rw-r--r-- | doc/tags | 1 | ||||
| -rw-r--r-- | lua/muwiki/config.lua | 7 | ||||
| -rw-r--r-- | lua/muwiki/external.lua | 29 | ||||
| -rw-r--r-- | lua/muwiki/health.lua | 4 | ||||
| -rw-r--r-- | lua/muwiki/init.lua | 2 | ||||
| -rw-r--r-- | lua/muwiki/io.lua | 161 | ||||
| -rw-r--r-- | lua/muwiki/links.lua | 112 | ||||
| -rw-r--r-- | lua/muwiki/paths.lua | 20 | ||||
| -rw-r--r-- | lua/muwiki/template.lua | 35 | ||||
| -rw-r--r-- | lua/muwiki/utils.lua | 57 |
12 files changed, 210 insertions, 380 deletions
@@ -12,7 +12,6 @@ A lightweight wiki plugin for Neovim using standard markdown syntax. - Standard markdown links `[text](url)` - Multiple wiki directories - External link handlers -- Automatic template for new page - Link navigation with custom keymaps See `:help muwiki` for complete documentation and configuration options. @@ -37,14 +36,16 @@ Using [lazy.nvim](https://github.com/folke/lazy.nvim): local muwiki = require('muwiki') muwiki.setup(opts) - local group = vim.api.nvim_create_augroup("MuWikiKeymaps", { clear = true }) + local group = vim.api.nvim_create_augroup("muwiki", { clear = true }) + -- Setup wiki keymaps for markdown files vim.api.nvim_create_autocmd("FileType", { group = group, pattern = "markdown", - callback = function(ev) - if not muwiki.wiki_root(ev.buf) then return end - local keymap_opts = { buffer = ev.buf, silent = true, nowait = true } + callback = function(args) + if not muwiki.wiki_root(args.buf) then return end + + local keymap_opts = { buffer = args.buf, silent = true, nowait = true } vim.keymap.set('n', '<CR>', muwiki.open_link, keymap_opts) vim.keymap.set('n', '<Tab>', muwiki.next_link, keymap_opts) vim.keymap.set('n', '<S-Tab>', muwiki.prev_link, keymap_opts) @@ -52,6 +53,23 @@ Using [lazy.nvim](https://github.com/folke/lazy.nvim): vim.keymap.set('n', '<leader>oo', muwiki.open_link_with, keymap_opts) end, }) + + -- Auto-create parent directories when saving files in wiki + vim.api.nvim_create_autocmd("BufWritePre", { + group = group, + callback = function(args) + local wiki_root = muwiki.wiki_root(args.buf) + if not wiki_root then return end + + local file = args.file + if not vim.startswith(file, wiki_root) then return end + + local dir = vim.fn.fnamemodify(file, ":h") + if vim.fn.isdirectory(dir) == 0 then + vim.fn.mkdir(dir, "p") + end + end, + }) end, } ``` diff --git a/doc/muwiki.txt b/doc/muwiki.txt index 4576388..878095d 100644 --- a/doc/muwiki.txt +++ b/doc/muwiki.txt @@ -12,7 +12,6 @@ CONTENTS *muwiki-contents* 5. Keymaps ................................ |muwiki-keymaps| 6. Link Format ............................ |muwiki-link-format| 7. External Handlers ...................... |muwiki-external-handlers| -8. Templates .............................. |muwiki-templates| ============================================================================== 1. INTRODUCTION *muwiki-introduction* @@ -24,7 +23,6 @@ Features:~ - Standard markdown links `[text](url)` - Multiple wiki directories support - External link handlers for custom URL/file opening -- Automatic templates for new pages - Link navigation with custom keymaps Requirements:~ @@ -51,20 +49,39 @@ Using lazy.nvim:~ local muwiki = require('muwiki') muwiki.setup(opts) - local group = vim.api.nvim_create_augroup("MuWikiKeymaps", { clear = true }) + local group = vim.api.nvim_create_augroup("muwiki", { clear = true }) + -- Setup wiki keymaps for markdown files vim.api.nvim_create_autocmd("FileType", { group = group, pattern = "markdown", - callback = function(ev) - if not muwiki.wiki_root(ev.buf) then return end - local keymap_opts = { buffer = ev.buf, silent = true, nowait = true } + callback = function(args) + if not muwiki.wiki_root(args.buf) then return end + + local keymap_opts = { buffer = args.buf, silent = true, nowait = true } vim.keymap.set('n', '<CR>', muwiki.open_link, keymap_opts) vim.keymap.set('n', '<Tab>', muwiki.next_link, keymap_opts) vim.keymap.set('n', '<S-Tab>', muwiki.prev_link, keymap_opts) vim.keymap.set('v', '<CR>', muwiki.create_link, keymap_opts) end, }) + + -- Auto-create parent directories when saving files in wiki + vim.api.nvim_create_autocmd("BufWritePre", { + group = group, + callback = function(args) + local wiki_root = muwiki.wiki_root(args.buf) + if not wiki_root then return end + + local file = args.file + if not vim.startswith(file, wiki_root) then return end + + local dir = vim.fn.fnamemodify(file, ":h") + if vim.fn.isdirectory(dir) == 0 then + vim.fn.mkdir(dir, "p") + end + end, + }) end, } < @@ -79,15 +96,6 @@ Configuration Options:~ index_file Name of the wiki index file Default: 'index.md' - date_fmt Date format string for templates - Default: '%Y-%m-%d' - - use_template Enable automatic templates for new pages - Default: false - - template Template content with placeholders - See |muwiki-templates| - use_external_handlers Enable external URL/file handlers Default: false @@ -101,15 +109,6 @@ Configuration Options:~ to force editor opening. Default: { 'md', 'txt' } - create_missing_dirs Automatically create missing parent directories - when opening or creating wiki files. - Values: - false - Don't create directories (default) - 'notify' - Create and show notification - 'prompt' - Ask before creating - Directories are only created within wiki root. - Default: false - Example:~ >lua { @@ -124,15 +123,6 @@ Example:~ { name = 'test', path = '~/wiki_test' }, }, index_file = 'index.md', - create_missing_dirs = 'notify', - date_fmt = '%Y-%m-%d', - use_template = true, - template = [[ - --- - title: ${title} - date: ${date} - --- - ]], text_extensions = { 'md', 'txt' }, use_external_handlers = true, external_handlers = { @@ -168,14 +158,16 @@ Example:~ local muwiki = require('muwiki') muwiki.setup(opts) - local group = vim.api.nvim_create_augroup("MuWikiKeymaps", { clear = true }) + local group = vim.api.nvim_create_augroup("muwiki", { clear = true }) + -- Setup wiki keymaps for markdown files vim.api.nvim_create_autocmd("FileType", { group = group, pattern = "markdown", - callback = function(ev) - if not muwiki.wiki_root(ev.buf) then return end - local keymap_opts = { buffer = ev.buf, silent = true, nowait = true } + callback = function(args) + if not muwiki.wiki_root(args.buf) then return end + + local keymap_opts = { buffer = args.buf, silent = true, nowait = true } vim.keymap.set('n', '<CR>', muwiki.open_link, keymap_opts) vim.keymap.set('n', '<Tab>', muwiki.next_link, keymap_opts) vim.keymap.set('n', '<S-Tab>', muwiki.prev_link, keymap_opts) @@ -183,6 +175,23 @@ Example:~ vim.keymap.set('n', '<leader>oo', muwiki.open_link_with, keymap_opts) end, }) + + -- Auto-create parent directories when saving files in wiki + vim.api.nvim_create_autocmd("BufWritePre", { + group = group, + callback = function(args) + local wiki_root = muwiki.wiki_root(args.buf) + if not wiki_root then return end + + local file = args.file + if not vim.startswith(file, wiki_root) then return end + + local dir = vim.fn.fnamemodify(file, ":h") + if vim.fn.isdirectory(dir) == 0 then + vim.fn.mkdir(dir, "p") + end + end, + }) end, } < @@ -277,14 +286,16 @@ Configure keymaps using an autocmd to ensure they only apply within wiki directories: >lua local muwiki = require('muwiki') - local group = vim.api.nvim_create_augroup("MuWikiKeymaps", { clear = true }) + local group = vim.api.nvim_create_augroup("muwiki", { clear = true }) + -- Setup wiki keymaps for markdown files vim.api.nvim_create_autocmd("FileType", { group = group, pattern = "markdown", - callback = function(ev) - if not muwiki.wiki_root(ev.buf) then return end - local opts = { buffer = ev.buf, silent = true, nowait = true } + callback = function(args) + if not muwiki.wiki_root(args.buf) then return end + + local opts = { buffer = args.buf, silent = true, nowait = true } vim.keymap.set('n', '<CR>', muwiki.open_link, opts) vim.keymap.set('n', '<Tab>', muwiki.next_link, opts) vim.keymap.set('n', '<S-Tab>', muwiki.prev_link, opts) @@ -292,6 +303,23 @@ directories: >lua vim.keymap.set('n', '<leader>oo', muwiki.open_link_with, opts) end, }) + + -- Auto-create parent directories when saving files in wiki + vim.api.nvim_create_autocmd("BufWritePre", { + group = group, + callback = function(args) + local wiki_root = muwiki.wiki_root(args.buf) + if not wiki_root then return end + + local file = args.file + if not vim.startswith(file, wiki_root) then return end + + local dir = vim.fn.fnamemodify(file, ":h") + if vim.fn.isdirectory(dir) == 0 then + vim.fn.mkdir(dir, "p") + end + end, + }) < Note: Actions check if the buffer is within a configured wiki directory and notify the user if not. @@ -409,30 +437,6 @@ Example: Open PNG files in Neovim (as text/hex) instead of external viewer:~ text_extensions = { 'md', 'txt', 'png' } < ============================================================================== -8. TEMPLATES *muwiki-templates* - -Automatic templates can be applied when creating new wiki pages. - -Enable templates:~ ->lua - require("muwiki").setup({ - use_template = true, - }) -< -Template Placeholders:~ - - ${title} Page title (derived from filename) - ${date} Current date (formatted with `date_fmt`) - -Default Template:~ ->lua - template = [[ ---- -title: ${title} -date: ${date} ---- -]] -< ============================================================================== HEALTH CHECKING *muwiki-health* @@ -7,7 +7,6 @@ muwiki-installation muwiki.txt /*muwiki-installation* muwiki-introduction muwiki.txt /*muwiki-introduction* muwiki-keymaps muwiki.txt /*muwiki-keymaps* muwiki-link-format muwiki.txt /*muwiki-link-format* -muwiki-templates muwiki.txt /*muwiki-templates* muwiki.next_link() muwiki.txt /*muwiki.next_link()* muwiki.open_index() muwiki.txt /*muwiki.open_index()* muwiki.open_link() muwiki.txt /*muwiki.open_link()* diff --git a/lua/muwiki/config.lua b/lua/muwiki/config.lua index 1e7e3de..1e04d4a 100644 --- a/lua/muwiki/config.lua +++ b/lua/muwiki/config.lua @@ -3,12 +3,6 @@ local M = {} M.options = { dirs = nil, index_file = 'index.md', - date_fmt = '%Y-%m-%d', - use_template = false, - template = [[ -title: ${title} -date: ${date} -]], text_extensions = { 'md', 'txt' }, use_external_handlers = false, external_handlers = { @@ -18,7 +12,6 @@ date: ${date} pattern = '.*', }, }, - create_missing_dirs = false, } local function dir_exists(path) diff --git a/lua/muwiki/external.lua b/lua/muwiki/external.lua index cf26aca..9ea83b5 100644 --- a/lua/muwiki/external.lua +++ b/lua/muwiki/external.lua @@ -27,33 +27,4 @@ function M.execute(handler, url) end end -function M.matches(handler, url) - local pattern = handler.pattern - - if pattern == nil then - return true - end - - if type(pattern) == 'string' then - return url:match(pattern) ~= nil - end - - for _, p in ipairs(pattern) do - if url:match(p) then - return true - end - end - return false -end - -function M.get_matching(url) - local matching = {} - for _, handler in ipairs(config.options.external_handlers) do - if M.matches(handler, url) then - table.insert(matching, handler) - end - end - return matching -end - return M diff --git a/lua/muwiki/health.lua b/lua/muwiki/health.lua index 2dfd45b..22c9747 100644 --- a/lua/muwiki/health.lua +++ b/lua/muwiki/health.lua @@ -1,5 +1,5 @@ -local io_module = require('muwiki.io') +local utils = require('muwiki.utils') local M = {} @@ -26,7 +26,7 @@ M.check = function() vim.health.info('Add to your config: dirs = {{name = "default", path = "~/wiki"}}') else for _, dir in ipairs(cfg.dirs) do - if io_module.dir_exists(dir.path) then + if utils.dir_exists(dir.path) then vim.health.ok(string.format("Wiki '%s': %s", dir.name, dir.path)) else vim.health.warn(string.format("Wiki '%s': %s (not found)", dir.name, dir.path)) diff --git a/lua/muwiki/init.lua b/lua/muwiki/init.lua index 5538d91..a6997a7 100644 --- a/lua/muwiki/init.lua +++ b/lua/muwiki/init.lua @@ -27,7 +27,7 @@ function M.create_link() end function M.open_index(name) - require('muwiki.io').open_index(name) + require('muwiki.utils').open_index(name) end function M.wiki_root(bufnr) diff --git a/lua/muwiki/io.lua b/lua/muwiki/io.lua deleted file mode 100644 index e86fb2e..0000000 --- a/lua/muwiki/io.lua +++ /dev/null @@ -1,161 +0,0 @@ -local config = require('muwiki.config') -local paths = require('muwiki.paths') - -local M = {} - -function M.exists(path) - local stat = vim.uv.fs_stat(path) - return stat and stat.type or nil -end - -function M.file_exists(path) - return M.exists(path) == 'file' -end - -function M.dir_exists(path) - return M.exists(path) == 'directory' -end - -function M.create_dir_safely(dirpath, wiki_root) - if not paths.is_within_wiki(dirpath, wiki_root) then - return false, 'Directory is outside wiki root' - end - - if M.dir_exists(dirpath) then - return true, nil - end - - if vim.fn.mkdir(dirpath, 'p') ~= 1 then - return false, 'Failed to create directory' - end - - if not paths.is_within_wiki(dirpath, wiki_root) then - vim.fn.delete(dirpath, 'd') - return false, 'Symlink attack detected' - end - - return true, nil -end - -function M.ensure_parent_dirs(filepath, wiki_root, mode, callback) - local dirpath = vim.fs.dirname(filepath) - - if M.dir_exists(dirpath) then - if callback then - callback(true) - end - return true - end - - local function do_create() - local success, err = M.create_dir_safely(dirpath, wiki_root) - if not success then - vim.notify(string.format('Cannot create directory: %s', err), vim.log.levels.ERROR) - if callback then - callback(false) - end - return false - end - - if mode == 'notify' then - vim.notify(string.format('Created directory: %s', dirpath), vim.log.levels.INFO) - end - - if callback then - callback(true) - end - return true - end - - if mode == 'prompt' then - vim.ui.select({ 'Yes', 'No' }, { - prompt = string.format('Directory does not exist. Create %s?', dirpath), - }, function(choice) - if choice == 'Yes' then - do_create() - else - vim.notify('Directory creation cancelled', vim.log.levels.INFO) - if callback then - callback(false) - end - end - end) - return nil - end - - return do_create() -end - -function M.open_in_buffer(filepath) - local bufnr = vim.fn.bufnr(filepath, true) - vim.api.nvim_win_set_buf(0, bufnr) -end - -function M.open_index(name) - local wiki_path = config.wiki_path(name) - if not wiki_path then - return - end - - local index_path = vim.fs.joinpath(wiki_path, config.options.index_file) - M.open_in_buffer(index_path) -end - -function M.resolve(filepath, wiki_root) - if not wiki_root then - error('wiki_root parameter is required for secure path resolution') - end - - local path = paths.strip_file_protocol(filepath) - local resolved = paths.resolve(path, wiki_root) - return paths.validate_within_wiki(resolved, wiki_root, filepath) -end - -function M.is_text_file(ext) - local ext_lower = ext:lower() - for _, text_ext in ipairs(config.options.text_extensions) do - if ext_lower == text_ext then - return true - end - end - return false -end - -function M.normalize_filename(text) - local normalized = text:lower() - normalized = normalized:gsub('%s+', '_') - normalized = normalized:gsub('[^%w_%-%.]', '') - return normalized -end - -function M.open_wiki_file(filepath) - local template = require('muwiki.template') - local exists = M.file_exists(filepath) - - if not exists and config.options.create_missing_dirs then - local wiki_root = config.wiki_root(0) - if wiki_root then - local mode = config.options.create_missing_dirs - - if mode == 'prompt' then - M.ensure_parent_dirs(filepath, wiki_root, mode, function(success) - if success then - M.open_in_buffer(filepath) - template.init_file(vim.api.nvim_get_current_buf(), filepath) - end - end) - return - else - local success = M.ensure_parent_dirs(filepath, wiki_root, mode) - if not success then - return - end - end - end - end - - M.open_in_buffer(filepath) - template.init_file(vim.api.nvim_get_current_buf(), filepath) -end - -return M diff --git a/lua/muwiki/links.lua b/lua/muwiki/links.lua index 990ecb1..55ce692 100644 --- a/lua/muwiki/links.lua +++ b/lua/muwiki/links.lua @@ -1,6 +1,6 @@ local config = require('muwiki.config') local paths = require('muwiki.paths') -local io_module = require('muwiki.io') +local utils = require('muwiki.utils') local external = require('muwiki.external') local M = {} @@ -72,50 +72,6 @@ local function resolve_file_url(url) return 'file://' .. vim.fs.normalize(path) end -function M.handle_web_link(url) - if not config.options.use_external_handlers then - return - end - external.open(url) -end - -function M.handle_file_url(url) - if not config.options.use_external_handlers then - return - end - local absolute_url = resolve_file_url(url) - external.open(absolute_url) -end - -function M.handle_file_link(target, wiki_root) - local ok, file_path = pcall(io_module.resolve, target, wiki_root) - if not ok then - vim.notify(string.format('Cannot resolve path: %s', target), vim.log.levels.ERROR) - return - end - - if not io_module.file_exists(file_path) then - vim.notify(string.format('File not found: %s', file_path), vim.log.levels.ERROR) - return - end - - local ext = file_path:match('%.([^%.]+)$') or '' - if not io_module.is_text_file(ext) then - if not config.options.use_external_handlers then - return - end - external.open(file_path) - return - end - - io_module.open_in_buffer(file_path) -end - -function M.handle_wiki_link(target, wiki_root) - local file_path = io_module.resolve(target, wiki_root) - io_module.open_wiki_file(file_path) -end - local function get_wiki_root_or_notify() local wiki_root = config.wiki_root(0) if not wiki_root then @@ -133,7 +89,9 @@ function M.open_link() end if link.type == 'web' then - M.handle_web_link(link.target) + if config.options.use_external_handlers then + external.open(link.target) + end return end @@ -144,14 +102,38 @@ function M.open_link() if link.type == 'file' then if vim.startswith(link.target, 'file://') then - M.handle_file_url(link.target) + if config.options.use_external_handlers then + local absolute_url = resolve_file_url(link.target) + external.open(absolute_url) + end else - M.handle_file_link(link.target, wiki_root) + local ok, file_path = pcall(utils.resolve, link.target, wiki_root) + if not ok then + vim.notify(string.format('Cannot resolve path: %s', link.target), vim.log.levels.ERROR) + return + end + + if not utils.file_exists(file_path) then + vim.notify(string.format('File not found: %s', file_path), vim.log.levels.ERROR) + return + end + + local ext = file_path:match('%.([^%.]+)$') or '' + if not utils.is_text_file(ext) then + if config.options.use_external_handlers then + external.open(file_path) + end + return + end + + utils.open_in_buffer(file_path) end return end - M.handle_wiki_link(link.target, wiki_root) + -- wiki link + local file_path = utils.resolve(link.target, wiki_root) + utils.open_wiki_file(file_path) end function M.open_link_with() @@ -172,10 +154,32 @@ function M.open_link_with() if not wiki_root then return end - url = io_module.resolve(url, wiki_root) + url = utils.resolve(url, wiki_root) end - local matching_handlers = external.get_matching(url) + -- Find matching handlers for URL + local function handler_matches(handler, url) + local pattern = handler.pattern + if pattern == nil then + return true + end + if type(pattern) == 'string' then + return url:match(pattern) ~= nil + end + for _, p in ipairs(pattern) do + if url:match(p) then + return true + end + end + return false + end + + local matching_handlers = {} + for _, handler in ipairs(config.options.external_handlers) do + if handler_matches(handler, url) then + table.insert(matching_handlers, handler) + end + end if #matching_handlers == 0 then vim.notify('No handlers available for this URL', vim.log.levels.WARN) @@ -223,7 +227,7 @@ function M.create_link() end local selected_text = region[1] - local normalized = io_module.normalize_filename(selected_text) + local normalized = utils.normalize_filename(selected_text) local link_target = normalized .. '.md' local link_text = string.format('[%s](%s)', selected_text, link_target) @@ -256,8 +260,8 @@ function M.create_link() return end - local target_path = io_module.resolve(link_target, wiki_root) - io_module.open_wiki_file(target_path) + local target_path = utils.resolve(link_target, wiki_root) + utils.open_wiki_file(target_path) end local function jump_link(direction) diff --git a/lua/muwiki/paths.lua b/lua/muwiki/paths.lua index f679888..c2f8fdb 100644 --- a/lua/muwiki/paths.lua +++ b/lua/muwiki/paths.lua @@ -26,26 +26,6 @@ function M.strip_file_protocol(url) return url:gsub('^file://', '') end -function M.is_within_wiki(filepath, wiki_root) - local real_path = vim.fn.resolve(filepath) - local real_root = vim.fn.resolve(wiki_root) - - local normalized_path = vim.fs.normalize(real_path) - local normalized_root = vim.fs.normalize(real_root) - - return vim.startswith(normalized_path, normalized_root) -end - -function M.validate_within_wiki(resolved_path, wiki_root, original_path) - if not M.is_within_wiki(resolved_path, wiki_root) then - vim.notify( - string.format('Warning: Resolved path outside wiki root: %s', original_path), - vim.log.levels.WARN - ) - end - return resolved_path -end - local ALLOWED_SCHEMES = { http = true, https = true, diff --git a/lua/muwiki/template.lua b/lua/muwiki/template.lua deleted file mode 100644 index d8eca16..0000000 --- a/lua/muwiki/template.lua +++ /dev/null @@ -1,35 +0,0 @@ -local config = require('muwiki.config') -local io_module = require('muwiki.io') - -local M = {} - -local function process_template(template, title) - local date_fmt = config.options.date_fmt or '%Y-%m-%d' - local date = os.date(date_fmt) - local result = template:gsub('${title}', title):gsub('${date}', date) - - if not result:match('\n$') then - result = result .. '\n' - end - - return result -end - -function M.init_file(bufnr, filepath) - if io_module.file_exists(filepath) then - return - end - - local filename = vim.fs.basename(filepath) - - if config.options.use_template then - local title = filename:gsub('%.md$', ''):gsub('_', ' ') - local content = process_template(config.options.template, title) - local lines = vim.split(content, '\n', { plain = true }) - vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) - end - - vim.notify(string.format('%s (unsaved)', filename), vim.log.levels.INFO) -end - -return M diff --git a/lua/muwiki/utils.lua b/lua/muwiki/utils.lua new file mode 100644 index 0000000..af22c8e --- /dev/null +++ b/lua/muwiki/utils.lua @@ -0,0 +1,57 @@ +local config = require('muwiki.config') +local paths = require('muwiki.paths') + +local M = {} + +function M.file_exists(path) + local stat = vim.uv.fs_stat(path) + return stat and stat.type == 'file' +end + +function M.dir_exists(path) + local stat = vim.uv.fs_stat(path) + return stat and stat.type == 'directory' +end + +function M.open_in_buffer(filepath) + local bufnr = vim.fn.bufnr(filepath, true) + vim.api.nvim_win_set_buf(0, bufnr) +end + +function M.open_index(name) + local wiki_path = config.wiki_path(name) + if not wiki_path then + return + end + + local index_path = vim.fs.joinpath(wiki_path, config.options.index_file) + M.open_in_buffer(index_path) +end + +function M.resolve(filepath, wiki_root) + local path = paths.strip_file_protocol(filepath) + return paths.resolve(path, wiki_root) +end + +function M.is_text_file(ext) + local ext_lower = ext:lower() + for _, text_ext in ipairs(config.options.text_extensions) do + if ext_lower == text_ext then + return true + end + end + return false +end + +function M.normalize_filename(text) + local normalized = text:lower() + normalized = normalized:gsub('%s+', '_') + normalized = normalized:gsub('[^%w_%-%.]', '') + return normalized +end + +function M.open_wiki_file(filepath) + M.open_in_buffer(filepath) +end + +return M |
