Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: respect language settings of imported files #75

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions lua/cspell/code_actions/init.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
local make_builtin = require("null-ls.helpers").make_builtin
local u = require("null-ls.utils")
local methods = require("null-ls.methods")
local h = require("cspell.helpers")
local helpers = require("cspell.helpers")
local make_add_to_json = require("cspell.code_actions.make_add_to_json")
local make_add_to_dictionary_action = require("cspell.code_actions.make_add_to_dictionary_action")

Expand Down Expand Up @@ -30,10 +29,10 @@ local get_config_info = function(code_action_config, params, cspell_json_path)
-- should already have been loaded, that's why we're defaulting reading the
-- config synchronously here.
if code_action_config.read_config_synchronously then
return h.sync_get_config_info(params, cspell_json_path)
return helpers.sync_get_config_info(params, cspell_json_path)
end

return h.async_get_config_info(params, cspell_json_path)
return helpers.async_get_config_info(params, cspell_json_path)
end

return make_builtin({
Expand All @@ -55,7 +54,7 @@ return make_builtin({
---@param params GeneratorParams
---@return table<number, CodeAction>
fn = function(params)
params.cwd = params.cwd or u.get_root()
helpers.update_params_cwd(params)

---@type CSpellSourceConfig
local code_action_config =
Expand All @@ -68,9 +67,9 @@ return make_builtin({
table.insert(cspell_config_directories, params.cwd)

for _, cspell_config_directory in pairs(cspell_config_directories) do
local cspell_config_path = h.get_config_path(params, cspell_config_directory)
local cspell_config_path = helpers.get_config_path(params, cspell_config_directory)
if cspell_config_path == nil then
cspell_config_path = h.generate_cspell_config_path(params, cspell_config_directory)
cspell_config_path = helpers.generate_cspell_config_path(params, cspell_config_directory)
end
cspell_config_paths[cspell_config_directory] = cspell_config_path
end
Expand Down Expand Up @@ -100,7 +99,7 @@ return make_builtin({
table.insert(actions, {
title = string.format("%s: %s", kind, suggestion),
action = function()
h.set_word(diagnostic, suggestion)
helpers.set_word(diagnostic, suggestion)

local on_success = code_action_config.on_success
local on_use_suggestion = code_action_config.on_use_suggestion
Expand Down Expand Up @@ -132,7 +131,7 @@ return make_builtin({
})
end

local word = h.get_word(diagnostic)
local word = helpers.get_word(diagnostic)
local dictionary_cspell_configs = {}

for _, cspell_config_path in pairs(cspell_config_paths) do
Expand Down
8 changes: 5 additions & 3 deletions lua/cspell/diagnostics/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ return h.make_builtin({
params.ft,
"stdin://" .. params.bufname,
}
params.cwd = params.cwd or vim.loop.cwd()
local force_rewrite = helpers.update_params_cwd(params)

---@type CSpellSourceConfig
local diagnostics_config = params and params:get_config() or {}

---@type table<number|string, string>
local cspell_config_paths = {}
local cspell_config_paths = diagnostics_config.cspell_import_files
and diagnostics_config.cspell_import_files(params)
or {}

local cspell_config_directories = diagnostics_config.cspell_config_dirs or {}
table.insert(cspell_config_directories, params.cwd)
Expand All @@ -43,7 +45,7 @@ return h.make_builtin({
end
cspell_config_paths[cspell_config_directory] = cspell_config_path
end
local merged_config = helpers.create_merged_cspell_json(params, cspell_config_paths)
local merged_config = helpers.create_merged_cspell_json(params, cspell_config_paths, force_rewrite)

cspell_args = vim.list_extend({ "-c", merged_config.path }, cspell_args)

Expand Down
103 changes: 87 additions & 16 deletions lua/cspell/helpers.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local Path = require("plenary.path")
local logger = require("null-ls.logger")
local u = require("null-ls.utils")

local M = {}
local CACHED_JSON_WORDS = {}
Expand All @@ -16,6 +17,22 @@ local CONFIG_INFO_BY_PATH = {}
---@type table<string, string|nil>
local PATH_BY_DIRECTORY = {}

local cspell_config_read_languages = function(cspell_config_path)
local language_list = {}
local ok, cspell_config = pcall(vim.json.decode, Path:new(cspell_config_path):read())
if
ok
and cspell_config.language ~= nil
and type(cspell_config.language) == "string"
and cspell_config.language ~= ""
then
for language in (cspell_config.language .. ","):gmatch("(.-)" .. ",") do
table.insert(language_list, language)
end
end
return language_list
end

local create_cspell_json = function(params, cspell_json, cspell_json_file_path)
---@type CSpellSourceConfig
local code_action_config = params:get_config()
Expand Down Expand Up @@ -47,6 +64,14 @@ local set_create = function(itable)
return set
end

local set_to_list = function(set)
local list = {}
for key, _ in pairs(set) do
table.insert(list, key)
end
return list
end

local set_compare = function(expected_values, new_values)
for key, _ in pairs(expected_values) do
if new_values[key] == nil then
Expand All @@ -60,30 +85,26 @@ end
M.get_merged_cspell_json_path = function(params)
local vim_cache = vim.fn.stdpath("cache")
local plugin_name = "cspell.nvim"
local merged_config_key = Path:new(params.cwd):joinpath("cspell.json"):absolute():gsub("/", "-"):gsub(":", "")
local merged_config_key =
Path:new(params.cwd):joinpath("cspell.json"):absolute():gsub("\\", "-"):gsub("/", "-"):gsub(":", "")
local merged_config_path = Path:new(vim_cache):joinpath(plugin_name):joinpath(merged_config_key):absolute()

return merged_config_path
end

--- create a merged cspell.json file that imports all cspell configs defined in cspell_config_dirs
---@param params GeneratorParams
---@param cspell_config_mapping table<number|string, string>
---@return CSpellConfigInfo
M.create_merged_cspell_json = function(params, cspell_config_mapping)
local merged_config_path = M.get_merged_cspell_json_path(params)

---@return CSpellConfig
local get_merged_cspell_json = function(cspell_config_mapping)
local cspell_config_paths = {}

if CONFIG_INFO_BY_PATH[merged_config_path] ~= nil then
return CONFIG_INFO_BY_PATH[merged_config_path]
end

local language_list = {}
for _, cspell_config_path in pairs(cspell_config_mapping) do
local path_exists = cspell_config_path ~= nil
and cspell_config_path ~= ""
and Path:new(cspell_config_path):exists()
if path_exists then
for _, language in ipairs(cspell_config_read_languages(cspell_config_path)) do
table.insert(language_list, language)
end
table.insert(cspell_config_paths, cspell_config_path)
else
local debug_message = M.format(
Expand All @@ -94,16 +115,39 @@ M.create_merged_cspell_json = function(params, cspell_config_mapping)
end
end

local cspell_json = {
local languages = table.concat(set_to_list(set_create(language_list)), ",")
if languages == "" then
languages = "en"
end

return {
version = "0.2",
language = "en",
language = languages,
words = {},
flagWords = {},
import = cspell_config_paths,
}
end

local existing_config = M.get_cspell_config(params, merged_config_path)
--- create a merged cspell.json file that imports all cspell configs defined in cspell_config_dirs
---@param params GeneratorParams
---@param cspell_config_mapping table<number|string, string>
---@param force_rewrite boolean
---@return CSpellConfigInfo
M.create_merged_cspell_json = function(params, cspell_config_mapping, force_rewrite)
local merged_config_path = M.get_merged_cspell_json_path(params)

if force_rewrite then
local cspell_json = get_merged_cspell_json(cspell_config_mapping)
return create_cspell_json(params, cspell_json, merged_config_path)
end

if CONFIG_INFO_BY_PATH[merged_config_path] ~= nil then
return CONFIG_INFO_BY_PATH[merged_config_path]
end

local cspell_json = get_merged_cspell_json(cspell_config_mapping)
local existing_config = M.get_cspell_config(params, merged_config_path)
if existing_config ~= nil then
local existing_import_set = set_create(existing_config.config.import)
local new_import_set = set_create(cspell_json.import)
Expand Down Expand Up @@ -227,7 +271,7 @@ M.generate_cspell_config_path = function(params, directory)
config_file_preferred_name = "cspell.json"
end

local config_path = require("null-ls.utils").path.join(directory, config_file_preferred_name)
local config_path = u.path.join(directory, config_file_preferred_name)
return vim.fs.normalize(config_path)
end

Expand Down Expand Up @@ -351,6 +395,30 @@ M.set_word = function(diagnostic, new_word)
)
end

---@param params GeneratorParams
---@return boolean
local reset_cspell = function(params)
return params:get_config().reset_cspell and params:get_config().reset_cspell(params)
end

---@param params GeneratorParams
---@return string
local get_cwd = function(params)
return params:get_config().cwd and params:get_config().cwd(params) or u.get_root()
end

---@param params GeneratorParams
---@return boolean
M.update_params_cwd = function(params)
params.cwd = get_cwd(params)
if reset_cspell(params) then
M.clear_cache()
return true
else
return false
end
end

M.clear_cache = function()
CONFIG_INFO_BY_PATH = {}
PATH_BY_DIRECTORY = {}
Expand Down Expand Up @@ -418,6 +486,9 @@ return M
---@class CSpellSourceConfig
---@field config_file_preferred_name string|nil
---@field cspell_config_dirs table|nil
---@field cwd function|nil
---@field reset_cspell function|nil
---@field cspell_import_files function|nil
--- Will find and read the cspell config file synchronously, as soon as the
--- code actions generator gets called.
---
Expand Down
1 change: 1 addition & 0 deletions tests/run.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nvim --headless --noplugin -u tests/minimal_init.lua -c "lua require('plenary.test_harness').test_directory_command('tests/spec {minimal_init = \"tests/minimal_init.lua\"}')"