Files
darcula_nvim/nvim/lua/darcula/cspell/init.lua
2026-03-31 12:07:49 -05:00

212 lines
5.8 KiB
Lua

-- The MIT License (MIT)
--
-- Copyright © 2026 Scott E. Graves <scott.e.graves@protonmail.com>
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-- and associated documentation files (the “Software”), to deal in the Software without restriction,
-- including without limitation the rights to use, copy, modify, merge, publish, distribute,
-- sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in all copies or
-- substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-- BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--
local utils = require("darcula.utils")
local utils_os = require("darcula.utils.os")
local user_directory =
vim.fs.joinpath(
utils.iff(utils_os.is_windows, vim.env.NV_DARCULA_DRIVE, vim.env.HOME),
".desktop"
)
local user_dictionary =
vim.fs.joinpath(user_directory, ".cspell", "user_words.txt")
local config_data = {
"{",
' "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",',
' "version": "0.2",',
' "dictionaries": ["workspace-words", "user-words"],',
' "dictionaryDefinitions": [{',
' "name": "workspace-words",',
' "path": "./.cspell/words.txt",',
' "addWords": true',
" },",
" {",
' "name": "user-words",',
' "path": "' .. user_dictionary .. '",',
' "addWords": true',
" }",
" ]",
"}"
}
local get_workspace_directory = function()
return vim.fs.joinpath(NV_Darcula_Git_Root(vim.fn.getcwd()))
end
local get_workspace_dictionary = function()
return vim.fs.joinpath(get_workspace_directory(), ".cspell", "words.txt")
end
local create_config_file = function(force)
force = force and true
if
force or vim.fn.filereadable(get_workspace_dictionary()) ~= 0 or
vim.fn.filereadable(user_dictionary) ~= 0
then
local config_file =
vim.fs.joinpath(get_workspace_directory(), "cspell.json")
if vim.fn.filereadable(config_file) == 0 then
vim.fn.writefile(config_data, config_file, "b")
end
end
end
local refresh_buffer = function()
-- NV_Darcula_Refresh_Buffer()
NV_Darcula_LSP_Restart()
end
local group =
utils.augroup_with_autocmd(
"cspell_cfg",
"User",
"RooterChDir",
function()
create_config_file(false)
end
)
utils.autocmd(
group,
"VimEnter",
"*",
function()
create_config_file(false)
end
)
NV_Darcula_Cspell_Cleanup = function()
local get_lines = function(location)
if vim.fn.filereadable(location) ~= 0 then
return vim.fn.readfile(location, "")
end
return {}
end
local cleanup = function(lines)
local clean_lines = {}
for _, word in pairs(lines) do
word = vim.fn.trim(word:lower())
if #word > 0 and not table.contains(clean_lines, word) then
table.insert(clean_lines, word)
end
end
return clean_lines
end
local user_lines = cleanup(get_lines(user_dictionary))
local workspace_lines = cleanup(get_lines(get_workspace_dictionary()))
if vim.fn.filereadable(user_dictionary) ~= 0 then
table.sort(user_lines)
vim.fn.writefile(user_lines, user_dictionary, "b")
if vim.fn.filereadable(get_workspace_dictionary()) ~= 0 then
local unique_lines = {}
for _, word in pairs(workspace_lines) do
if not table.contains(user_lines, word) then
table.insert(unique_lines, word)
end
end
table.sort(unique_lines)
vim.fn.writefile(unique_lines, get_workspace_dictionary(), "b")
refresh_buffer()
end
end
vim.notify("Cleaned cspell dictionaries", vim.log.levels.INFO)
end
local cspell_read_file = function(user)
user = user or false
local spell_directory =
vim.fs.joinpath(
utils.iff(user, user_directory, get_workspace_directory()),
".cspell"
)
local is_directory = vim.fn.isdirectory(spell_directory)
if is_directory == 0 then
vim.fn.mkdir(spell_directory, "p")
end
create_config_file(true)
local spell_file = vim.fs.joinpath(spell_directory, "words.txt")
local lines = (function()
if vim.fn.filereadable(spell_file) ~= 0 then
return vim.fn.readfile(spell_file, "")
end
return {}
end)()
return lines, spell_file
end
local cspell_write_word = function(user, lines, spell_file, word)
user = user or false
word = vim.fn.trim(word)
if word ~= nil and #word > 0 and lines ~= nil then
for _, value in pairs(lines) do
if word:lower() == value:lower() then
return
end
end
table.insert(lines, word:lower())
table.sort(lines)
vim.fn.writefile(lines, spell_file, "b")
vim.notify(
"Added '" ..
word .. "' to " .. utils.iff(user, "user", "workspace") .. " dictionary",
vim.log.levels.INFO
)
refresh_buffer()
end
end
NV_Darcula_Cspell_Add_Selected_Word = function(user)
user = user or false
local lines, spell_file = cspell_read_file(user)
NV_Darcula_Grab_Selection(
function(word)
cspell_write_word(user, lines, spell_file, word)
end
)
end
NV_Darcula_Cspell_Add_Word = function(user)
user = user or false
local lines, spell_file = cspell_read_file(user)
local word = utils.cword() or ""
cspell_write_word(user, lines, spell_file, word)
end