aboutsummaryrefslogtreecommitdiff
path: root/lua/muwiki/utils.lua
blob: 5330e41b2f5976246b16a7b74c92f27fda85f098 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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