Thanks to visit codestin.com
Credit goes to github.com

Skip to content
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
14 changes: 0 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,6 @@ lua require('crates').setup()
</details>


<details>
<summary>For lazy loading.</summary>

```lua
{
'saecki/crates.nvim',
event = { "BufRead Cargo.toml" },
config = function()
require('crates').setup()
end,
}
```
</details>

## [Documentation](https://github.com/Saecki/crates.nvim/wiki)
- [Stable](https://github.com/Saecki/crates.nvim/wiki/Documentation-v0.7.1)
- [Unstable](https://github.com/Saecki/crates.nvim/wiki/Documentation-unstable)
Expand Down
56 changes: 26 additions & 30 deletions lua/crates/command.lua
Original file line number Diff line number Diff line change
@@ -1,41 +1,37 @@
local actions = require("crates.actions")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline these wrapped around a function to lazily require the modules😅 This seems to be improve the setup time from around 3ms to 0.5 ish for me

local core = require("crates.core")
local popup = require("crates.popup")

local M = {}

---@type {[1]: string, [2]: function}[]
local sub_commands = {
{ "hide", core.hide },
{ "show", core.show },
{ "toggle", core.toggle },
{ "update", core.update },
{ "reload", core.reload },
{ "hide", function() return require("crates.core").hide() end },
{ "show", function() return require("crates.core").show() end },
{ "toggle", function() return require("crates.core").toggle() end },
{ "update", function() return require("crates.core").update() end },
{ "reload", function() return require("crates.core").reload() end },

{ "upgrade_crate", actions.upgrade_crate },
{ "upgrade_crates", actions.upgrade_crates },
{ "upgrade_all_crates", actions.upgrade_all_crates },
{ "update_crate", actions.update_crate },
{ "update_crates", actions.update_crates },
{ "update_all_crates", actions.update_all_crates },
{ "use_git_source", actions.use_git_source },
{ "upgrade_crate", function() return require("crates.actions").upgrade_crate() end },
{ "upgrade_crates", function() return require("crates.actions").upgrade_crates() end },
{ "upgrade_all_crates", function() return require("crates.actions").upgrade_all_crates() end },
{ "update_crate", function() return require("crates.actions").update_crate() end },
{ "update_crates", function() return require("crates.actions").update_crates() end },
{ "update_all_crates", function() return require("crates.actions").update_all_crates() end },
{ "use_git_source", function() return require("crates.actions").use_git_source() end },

{ "expand_plain_crate_to_inline_table", actions.expand_plain_crate_to_inline_table },
{ "extract_crate_into_table", actions.extract_crate_into_table },
{ "expand_plain_crate_to_inline_table", function() return require("crates.actions").expand_plain_crate_to_inline_table() end },
{ "extract_crate_into_table", function() return require("crates.actions").extract_crate_into_table() end },

{ "open_homepage", actions.open_homepage },
{ "open_repository", actions.open_repository },
{ "open_documentation", actions.open_documentation },
{ "open_cratesio", actions.open_crates_io },
{ "open_homepage", function() return require("crates.actions").open_homepage() end },
{ "open_repository", function() return require("crates.actions").open_repository() end },
{ "open_documentation", function() return require("crates.actions").open_documentation() end },
{ "open_cratesio", function() return require("crates.actions").open_crates_io() end },

{ "popup_available", popup.available },
{ "show_popup", popup.show },
{ "show_crate_popup", popup.show_crate },
{ "show_versions_popup", popup.show_versions },
{ "show_features_popup", popup.show_features },
{ "show_dependencies_popup", popup.show_dependencies },
{ "focus_popup", popup.focus },
{ "hide_popup", popup.hide },
{ "popup_available", function() return require("crates.popup").available() end },
{ "show_popup", function() return require("crates.popup").show() end },
{ "show_crate_popup", function() return require("crates.popup").show_crate() end },
{ "show_versions_popup", function() return require("crates.popup").show_versions() end },
{ "show_features_popup", function() return require("crates.popup").show_features() end },
{ "show_dependencies_popup", function() return require("crates.popup").show_dependencies() end },
{ "focus_popup", function() return require("crates.popup").focus() end },
{ "hide_popup", function() return require("crates.popup").hide() end },
}

---@param arglead string
Expand Down
27 changes: 9 additions & 18 deletions lua/crates/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1993,35 +1993,26 @@ local function setup_neoconf(config)
end

---@param schema table<string,SchemaElement>|SchemaElement[]
---@param user_config table<string,any>
---@return table
local function build_config(schema, user_config)
local function build_config(schema)
---@type table<string,any>
local config = {}

for _, elem in ipairs(schema) do
local key = elem.name
local user_value = user_config[key]
local value_type = type(user_value)

if elem.type.config_type == "section" then
if value_type == "table" then
config[key] = build_config(elem.fields, user_value)
else
config[key] = build_config(elem.fields, {})
end
config[key] = build_config(elem.fields)
else
if matches_type(value_type, elem.type) then
config[key] = user_value
else
config[key] = elem.default
end
config[key] = elem.default
end
end

return config
end

local current_config = build_config(M.schema)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build the config once to be able to just deep_extend the user_config into the current config. This should make it possible to call setup multiple times without having any side effects on the users config option


---comment
---@param user_config table<string,any>?
---@return Config
Expand All @@ -2035,11 +2026,11 @@ function M.build(user_config)

handle_deprecated({}, M.schema, user_config, user_config)
validate_schema({}, M.schema, user_config)
local config = build_config(M.schema, user_config)
if config.neoconf.enabled then
return setup_neoconf(config)
current_config = vim.tbl_deep_extend("force", current_config, user_config)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will fail in some cases. For example if a scalar is provided by the user instead of a table, the config will now be invalid, because the default table will be overwritten.

Also unless I'm forgetting something the user config was never mutated to begin with, or did you hit some case where calling setup wasn't idempotent?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will fail in some cases. For example if a scalar is provided by the user instead of a table, the config will now be invalid, because the default table will be overwritten.

A few lines above it ensures that the user_config is a table, so I don't think that should be a problem

Also unless I'm forgetting something the user config was never mutated to begin with, or did you hit some case where calling setup wasn't idempotent?

The reason I changed it was because if calling setup once with for example { smart_insert = false }, and then again calling setup with {}, I would prefer it to still be { smart_insert = false }. This was not the case because build_config always preferred the default value over any missing values in the user provided config, and did not take into account the potential previous call to setup

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few lines above it ensures that the user_config is a table, so I don't think that should be a problem

I was talking about a nested table so for example { lsp = true } would overwrite the complete lsp configuration table.

The reason I changed it was because if calling setup once with for example { smart_insert = false }, and then again calling setup with {}, I would prefer it to still be { smart_insert = false }. This was not the case because build_config always preferred the default value over any missing values in the user provided config, and did not take into account the potential previous call to setup

Oh, I see. Maybe we could just extend the previous config before passing it into the build_config function. That way the config is still validated.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was talking about a nested table so for example { lsp = true } would overwrite the complete lsp configuration table.

Hmm good point. It should still use the default value in this case like the warning is saying that it does? Another option (maybe a bit hard) would be to just error instead of giving a warning

Oh, I see. Maybe we could just extend the previous config before passing it into the build_config function. That way the config is still validated.

Yeah I was thinking about that as well, but that would give a lot of warning about the user using deprecated options etc since the user_config is now the full config instead of only what the user provided🤔

if current_config.neoconf.enabled then
return setup_neoconf(current_config)
else
return config
return current_config
end
end

Expand Down
11 changes: 2 additions & 9 deletions lua/crates/init.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
local actions = require("crates.actions")
local async = require("crates.async")
local command = require("crates.command")
local config = require("crates.config")
local core = require("crates.core")
local highlight = require("crates.highlight")
local popup = require("crates.popup")
local state = require("crates.state")
local util = require("crates.util")

local function attach()
if state.cfg.completion.cmp.enabled then
Expand All @@ -18,15 +14,12 @@ local function attach()
end

core.update()
state.cfg.on_attach(util.current_buf())
state.cfg.on_attach(require("crates.util").current_buf())
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lazy require the util module until it is actually needed

end

---@param cfg crates.UserConfig
local function setup(cfg)
state.cfg = config.build(cfg)

command.register()
highlight.define()
state.cfg = require("crates.config").build(cfg)

---@type integer
local group = vim.api.nvim_create_augroup("Crates", {})
Expand Down
10 changes: 10 additions & 0 deletions plugin/crates.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require("crates.command").register()
require("crates.highlight").define()

vim.api.nvim_create_autocmd("BufRead", {
pattern = "Cargo.toml",
once = true,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create an autocmd that is fired once upon the first entry in a Cargo.toml file. This shouldn't change any option in case users have setup the plugin before this. Also, if the user calls setup after this, it should properly update the options accordingly

callback = function()
require("crates").setup({})
end,
})
Loading