local config = require('muwiki.config') local M = {} ---Open a file in Neovim buffer ---@param filepath string Absolute path to file function M.open_in_buffer(filepath) vim.cmd.edit(vim.fn.fnameescape(filepath)) end ---Lookup wiki path by name ---@param name string? Wiki name (uses first configured wiki if nil) ---@return string|nil path Absolute path to wiki directory, or nil if not configured function M.wiki_path(name) if not config.options.dirs or #config.options.dirs == 0 then vim.notify('MuWiki: No dirs configured. See :help muwiki-configuration', vim.log.levels.ERROR) return nil end if name then for _, dir in ipairs(config.options.dirs) do if dir.name == name then return dir.path end end vim.notify(string.format('Wiki "%s" not found, using default', name), vim.log.levels.WARN) end return config.options.dirs[1].path end ---Find which wiki contains this buffer's file (cached per-buffer) ---@param bufnr integer? Buffer number (defaults to 0 for current buffer) ---@return string|nil path Absolute path to wiki root, or nil if buffer is not in a wiki function M.wiki_root(bufnr) bufnr = bufnr or 0 if vim.b[bufnr].muwiki_root ~= nil then return vim.b[bufnr].muwiki_root or nil end local filepath = vim.api.nvim_buf_get_name(bufnr) local normalized = vim.fs.normalize(filepath) for _, dir in ipairs(config.options.dirs or {}) do if vim.startswith(normalized, dir.path) then vim.b[bufnr].muwiki_root = dir.path return dir.path end end vim.b[bufnr].muwiki_root = false return nil end ---Open the index file of a wiki ---@param name string? Wiki name (uses first configured wiki if nil) function M.open_index(name) local wiki_path = M.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 ---Resolve a path to absolute normalized form ---Strips file:// prefix and resolves relative paths against current buffer ---@param filepath string Path to resolve (can include file://, be relative, absolute, or ~) ---@return string Absolute normalized path function M.resolve(filepath) local path = filepath:gsub('^file://', '') -- Absolute paths: normalize directly if path:sub(1, 1) == '/' or path:sub(1, 1) == '~' then return vim.fs.normalize(path) end -- Relative paths: resolve against current buffer's directory local current_dir = vim.fs.dirname(vim.api.nvim_buf_get_name(0)) return vim.fs.normalize(vim.fs.joinpath(current_dir, path)) end ---Normalize text for use as filename ---Converts to lowercase, spaces to underscores, removes special chars ---@param text string Text to normalize ---@return string Normalized filename-safe text function M.normalize_filename(text) local normalized = text:lower() normalized = normalized:gsub('%s+', '_') normalized = normalized:gsub('[^%w_%-%.]', '') return normalized end return M