1M = {}
2
3---@class AcademicOptions
4M.opts = {
5 auto_install = true,
6 auto_rebuild = false,
7}
8
9local function get_root()
10 return vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":h:h")
11end
12
13local function get_dictionary()
14 local root = get_root()
15 local dict_path = root .. "/words/en-academic"
16 return dict_path
17end
18
19local function get_spell(dir)
20 local spell_dir = vim.fn["spellfile#WritableSpellDir"]() .. "/"
21 if dir then
22 return spell_dir
23 else
24 return spell_dir .. "en-academic"
25 end
26end
27
28---@param msg string # Message to show user before generation.
29M.generate_spellfile = function(msg)
30 vim.notify("Academic: " .. msg)
31 -- Create spell_dir if it doesn't exist
32 vim.fn.mkdir(get_spell(true), "p")
33 vim.cmd("mkspell! " .. get_spell() .. " " .. get_dictionary())
34 vim.notify("Academic: Done!")
35end
36
37local add_lang = function(lang)
38 local current = vim.opt.spelllang:get()
39 if not vim.tbl_contains(current, lang) then
40 table.insert(current, lang)
41 end
42 vim.opt.spelllang = current
43end
44
45local function get_spl_stat()
46 return vim.uv.fs_stat(get_spell() .. ".utf-8.spl") or vim.uv.fs_stat(get_spell() .. ".ascii.spl")
47end
48
49local function check_build()
50 local stat_plug = vim.uv.fs_stat(get_dictionary())
51 local stat_spell = get_spl_stat()
52 if not stat_plug then
53 vim.notify("Academic wordlist missing!", vim.log.levels.ERROR)
54 return false
55 else
56 if not stat_spell then
57 return true
58 end
59 end
60 -- helper function for time comparison
61 local function time(stat)
62 return stat.mtime.sec + stat.mtime.nsec * 1e-9
63 end
64 -- compare whether our wordlist is newer than user's generated one
65 if time(stat_plug) > time(stat_spell) then
66 return true
67 else
68 return false
69 end
70end
71
72M.update = function()
73 local cmd = { "bash", "-c", get_root() .. "/scripts/generate-wordlist.sh" }
74 local success = pcall(function()
75 vim.system(cmd, {}, function()
76 vim.notify("Academic dictionary updated!", vim.log.levels.INFO)
77 end)
78 end)
79 if not success then
80 vim.notify("Manual update requires bash, curl, and hunspell!", vim.log.levels.WARN)
81 end
82 M.load()
83end
84
85M.load = function()
86 -- We generate the spellfile if it doesn't exist
87 if M.opts.auto_install and not get_spl_stat() then
88 M.generate_spellfile("No spellfile, installing now...")
89 elseif M.opts.auto_rebuild and check_build() then
90 M.generate_spellfile("Spellfile out of date, rebuilding now...")
91 end
92 add_lang("en-academic")
93end
94
95M.setup = function(opts)
96 M.opts = vim.tbl_deep_extend("force", M.opts, opts or {})
97end
98
99return M