-
Notifications
You must be signed in to change notification settings - Fork 12
Customization
The best thing about neovim is how much it can be customized. Even here, with IceNvim, where so many things have been done for you already, you are still at liberty to customize almost anything to your own need.
First, find you got to find your config directory, which is ~/.config/nvim
for unix systems and ~/AppData/Local/nvim
for Windows system. This would be where you have git cloned the IceNvim repo and if you have done that already, you will see that there is a lua
directory here, and under it are the core
and plugins
directories.
π nvim
|-- π after
|-- π ftplugin
|-- π lua
|-- π core
|-- π plugins
|-- π screenshots
|-- π .gitignore
|-- π .stylua.toml
|-- π LICENSE
|-- π README.md
|-- π init.lua
IceNvim will be looking for a directory called custom
under lua
, and inside it, an init.lua
file. The directory is not tracked by git and the init.lua
file is loaded if present, which is how customization is enabled. So, if you want to enable customization, you should create the directory and the file, so your directory structure would be something like:
π nvim
|-- π after
|-- π ftplugin
|-- π lua
|-- π core
|-- π custom
|-- π init.lua
|-- π file-loaded-in-init.lua
|-- π plugins
|-- π screenshots
|-- π .gitignore
|-- π .stylua.toml
|-- π LICENSE
|-- π README.md
|-- π init.lua
You can, as you can see from above, also add other files in the custom
directory and load them in init.lua
.
IceNvim loads its configuration file following this procedure: it loads the core
module and the plugins
module and store the values in a global table called Ice
. What is loaded are things like keymaps and plugin configurations, but what is important is that, while I am using the word "load", they are actually only "stored" in the table. The keymaps are described but not yet set, and the plugins configuration are not yet accessed by the Lazy plugin manager (which means that up to now, the plugins are not loaded, something you ought to keep in mind when customizing later).
After this loading process, IceNvim goes on to loading the custom
module. Since Ice
now stores the default configuration and is globally accessible, you can now tweak with them however you want to. Also, while some settings done in core/basic.lua
have not been stored in the table, you can also easily override them in your custom/init.lua
file.
Afterwards, when your customization is finished, IceNvim uses the eventual Ice
table for setting keymaps and loading the plugins.
The most important thing you might want to know about customization is to add / remove a plugin or change its configuration. It is easy. All plugin configurations are stored in Ice.plugins
. Each plugin is stored as a table that can be recognized by Lazy (see its documentation). Adding a plugin mostly involves adding a key that is not already in Ice.plugins
and set its value to the proper table.
If you want to change how a plugin is loaded, you will need to look into how it is loaded by default by checking in lua/plugins/config.lua
, but it would not be too hard.
If you want to remove a plugin, just set its value to nil
.
For example
local view = Ice.plugins["nvim-tree"].opts.view
view.number = true
view.relativenumber = true
Ice.plugins.bufferline = nil
Lsp-related configurations are stored in Ice.lsp
. You can check out the defaults at lua/lsp/config.lua
.
Ice.lsp
is a table that maps a table to each server whose name you can find in mason, like css-lsp
and lua-language-server
. Each of these tables might contain these fields:
Set this if you want to associate a formatter with a particular lsp server; the formatter will be automatically set up by null-ls.
For example:
["json-lsp"] = {
formatter = "prettier",
}
This can either be a table that you use for nvim-lspconfig
or a function that returns such a table. For example:
gopls = {
formatter = "gofumpt",
setup = {
settings = {
gopls = {
analyses = {
unusedparams = true,
},
},
},
},
}
This is a special field. You might notice that there are fields in the default setup whose name are not found in mason, like rust
and flutter
. These are handled not by the conventional way of setting up an lsp, but are rather dealt with by external plugins. For these languages, you might want to explicitly set managed_by_plugin
to true
, which is false
by default.
You might wonder why this is necessary: why can we not just omit the table altogether? That is because we have one further field.
Another boolean value that indicates whether a language is enabled. The value is false
by default. IceNvim has presets for many languages but people probably do not want to enable all of them, especially upon the first startup, as mason would then start to download a lot of things which is quite time-consuming. The only enabled language is lua, by the name of lua-language-server
.
The existence of this field answers the question above: we need the managed_by_plugin
field because we also need to specify whether we want these plugin-handled languages to be enabled. If IceNvim is not informed that a particular language should not be handled by nvim-lspconfig, it would just do the same setup for that language which naturally leads to errors.
This part is a bit chaotic as IceNvim has placed the keymaps to where they should belong, namely by putting general plugins to the core module, plugin-related modules to plugin configurations and lsp-related plugins to the lsp part. Therefore, you might have to visit quite a lot of places to find all the keymaps.
This is a table that stores keymaps which do not require any plugin. The key is the desc
of the keymap, and the value is a table that contains the mode, lhs, rhs and options. For example:
Ice.keymap.general.black_hole_register = { { "n", "v" }, "\\", '"_' }
Note that options
can be omitted and rhs
can be either a string or a function. The desc
, i.e., the key here, will be the description in which-key.nvim.
Beware that, despite the name, this is where the keymaps for individual plugins are stored. Rather, these are keys mapped to functions not provided by the plugins themselves but which cannot function unless the plugins are installed. They follow the same format as Ice.keymap.general
.
Check the lazy.nvim documentation.
For example:
Ice.plugins.bufferline.keys = {
{ "<leader>bc", ":BufferLinePickClose<CR>", desc = "pick close", silent = true, noremap = true },
{ "<leader>bd", ":BufferLineClose 0<CR><ESC>", desc = "close current buffer", silent = true, noremap = true },
{ "<leader>bh", ":BufferLineCyclePrev<CR>", desc = "prev buffer", silent = true, noremap = true },
{ "<leader>bl", ":BufferLineCycleNext<CR>", desc = "next buffer", silent = true, noremap = true },
{ "<leader>bo", ":BufferLineCloseOthers<CR>", desc = "close others", silent = true, noremap = true },
{ "<leader>bp", ":BufferLinePick<CR>", desc = "pick buffer", silent = true, noremap = true },
}
These are stored in Ice.lsp.keymap
. Ice.lsp.keymap.mapLsp
follows the same mapping rule as Ice.keymap.general
, but Ice.lsp.keymap.cmp
follows a different rule. That is, we are mapping keys to a short description of a command. The implementation of these short commands are handled elsewhere, and this allows you to have a easier way of changing the key bindings. The commands and their default key bindings are:
-
show_completion
: <A-.> -
hide_completion
: <A-,> -
prev_item
: <C-k> -
next_item
: <C-j> -
confirm
: <Tab> -
doc_up
: <C-u> -
doc_down
: <C-d>
You can add a colorscheme by adding a field into Ice.colorschemes
. The value of that field would be a table that contains:
-
name
: the name of the colorscheme plugin -
background
: either"light"
or"dark"
-
setup
(optional): a function executed when setting the colorscheme
Note that the colorscheme has to be installed in Ice.plugins
first!
You can also set a colorscheme in Ice.colorscheme
(notice the missing "s" compared to above). The value has to be a key in Ice.colorschemes
. This way of setting the colorscheme has the highest priority. Without setting the value, the colorscheme picker provided by IceNvim would memorize your selected colorscheme, but once you set this value, whichever colorscheme you have picked in the colorscheme picker would be overridden in the next launch of neovim.
There also other keys in Ice
already taken. For now, they include:
Whether to enable automatic root directory switching. The default value is true
.
A table containing patterns that determine a root directory. The default pattern is:
{
".git",
"package.json",
".prettierrc",
"tsconfig.json",
"pubspec.yaml",
".gitignore",
"stylua.toml",
"README.md",
}
A table containing the file types not to enable automatic root directory switching for. The default value is:
{ "NvimTree", "help" }
A table containing the buffer types not to enable automatic root directory switching for. The default value is:
{ "terminal", "nofile" }
A table that defines what to do when a specific filetype is detected. For example, if you want to set colorcolumn
to 120, you can do this:
Ice.ft.javascript = function()
vim.wo.colorcolumn = "120"
end
If you want to disable colorcolumn in neogit, you can do this:
Ice.ft["Neogit*"] = function()
vim.wo.colorcolumn = ""
end
Some filetypes have default callbacks. If you want to add your own callback to them instead of just overriding them, you can use the Ice.ft:set()
method:
Ice.ft:set("typst", function ()
vim.wo.colorcolumn = "120"
end)
You can use the Ice.ft:set()
method on filetypes that do not have default values as well. Beware that it is :set()
instead of .set()
though.
A table that defines the nerd font icons for such symbols as function / number / object / string / ...
Neovim looks for such folders as queries
, ftplugin
, spell
, etc., in your runtimepath
. Typically, if one wishes to override the default treesitter queries or ftplugins or other things already set up by neovim, they would need to create the corresponding directory under their config directory.
However, that would prove inconvenient for IceNvim users as these new files would then be tracked by git and cause a lot of trouble. So the better way is to place the folders under lua/custom
as well. For example, where you should have ~/.config/nvim/queries/markdown/highlights.scm
, with IceNvim, it should be placed at ~/.config/nvim/queries/lua/custom/queries/markdown/highlights.scm
:
π nvim
|-- π after
|-- π ftplugin
|-- π lua
|-- π core
|-- π custom
|-- π init.lua
|-- π file-loaded-in-init.lua
|-- π queries
|-- π markdown
|-- π highlights.scm
|-- π plugins
|-- π screenshots
|-- π .gitignore
|-- π .stylua.toml
|-- π LICENSE
|-- π README.md
|-- π init.lua
For any problem you might encounter, you might want to first read through this wiki, as it contains quite a lot on how to use IceNvim properly.
Hope you enjoy using IceNvim.