Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bartste/nvim-projectrc
Manage your project specific neovim configuration.
https://github.com/bartste/nvim-projectrc
configuration lua neovim plugin project-management vim
Last synced: 21 days ago
JSON representation
Manage your project specific neovim configuration.
- Host: GitHub
- URL: https://github.com/bartste/nvim-projectrc
- Owner: BartSte
- License: mit
- Created: 2024-03-08T16:33:11.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2024-03-13T17:05:34.000Z (11 months ago)
- Last Synced: 2025-01-09T09:11:26.470Z (25 days ago)
- Topics: configuration, lua, neovim, plugin, project-management, vim
- Language: Lua
- Homepage:
- Size: 32.2 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# Projectrc
A minimal approach to manage your project specific settings in Neovim.
# Introduction
`nvim-projectrc` is a plugin for Neovim that allows you to manage your project
specific settings in a simple, yet effective way.I build this plugin because I have only small differences between my projects,
e.g., different text widths, linters, and language servers. I did not want to
create a new configuration file for each project, and I surely did not want to
place if statements all over my configuration. As such, `nvim-projectrc` is
based on the following requirements:- One global configuration file is used where each project makes its own
modifications to.
- It is easy to integrate in an existing configuration.
- The project identifier can be set from outside of Neovim, using an environment
variable.See the [usage](#usage) section for more information.
# Installation
Install the plugin using your favorite plugin manager. For example, using lazy:
```lua
return {
"BartSte/nvim-projectrc",
priority = 100,
lazy = false
}
```Lazy loading is not recommended as you need this plugin to load the configuration
of other plugins.# Usage
This plugin exposes the following 2 components that are of key interest:
- `PROJECTRC` environment variable
- `require("projectrc").require`Here, the `PROJECTRC` must be set before calling `require("projectrc").require`.
How you set the `PROJECTRC` is up to you. For example, you can set it to the
basename of the current working directory using the following bash alias:```bash
alias nvim='PROJECTRC=$(basename $(pwd)); nvim'
```The `require("projectrc").require` function takes a path to a directory
containing multiple configuration files. Here it will first try to source the
file with the name that corresponds to the `PROJECTRC` environment variable. If
this fails, it will try to source the file `default.lua`. If this fails, the
function returns `nil` by default.Lets illustrate this with some examples.
### Example - require
- `PROJECTRC` is set to `myproject`.
Now when you call `require("projectrc").require("/some/path")` the following
will happen:- It will try to source the file `/some/path/myproject.lua`.
- If this fails, it will try to source the file `/some/path/default.lua`.
- If this fails, the function returns `nil` by default.### Example - directory structure
Lets assume you have the following directory structure:
```ascii
nvim/
├── lua/
│ ├── config/lsp/
│ │ ├── init.lua -> servers you always need.
│ │ ├── default.lua -> default servers, no specific project settings.
│ │ └── myproject.lua -> specific servers for myproject.
│ │
... more files
```In you config, when you want to source you lsp configuration, you would call:
- `require("projectrc").require("config.lsp")`
If you `PROJECTRC` is set to `foo`, the following will happen:
- `config/lsp/init.lua` will always be sourced.
- it will try to source `config/lsp/foo.lua`, but this file does not exist.
- as a fallback, it will source `config/lsp/default.lua`.Now if you `PROJECTRC` is set to `myproject`, the following will happen:
- `config/lsp/init.lua` will always be sourced.
- it will try to source `config/lsp/myproject.lua`, and this file exists.Note that in the last case, the `default.lua` file is not sourced.
### Example - using lazy
In the example above, you would call the `require("projectrc").require` function
using the package manager [lazy](www.github.com/folke/lazy.nvim) as is explained
below.Lets assume you have the following project structure:
```ascii
nvim/
├── lua/
│ ├── config/lsp/
│ │ ├── init.lua -> servers you always need.
│ │ ├── default.lua -> default servers, no specific project settings.
│ │ └── myproject.lua -> specific servers for myproject.
│ └── plugins/lsp.lua -> containing the plugin spec.
... more files
```where the `plugins` directory is added to the `lazy.setup` function:
`lazy.setup("plugins", {})`. The `plugins/lsp.lua` may look as follows:```lua
return {
"neovim/nvim-lspconfig",
config = function()
require("projectrc").require("config.lsp")
end
}
```Similarly to the previous example, the `config/lsp/init.lua` will always be
sourced. The `myproject.lua` file will be sourced if `PROJECTRC` is set to
`myproject`, and the `default.lua` file will be sourced otherwise.### Example - ftplugin
Sometimes you want your project specific settings to be sourced when you enter a
file of a certain filetype. Lets say you want a textwidth of 100 for your
`myproject` config, and a textwidth of 80 otherwise. Furthermore, this only
needs to happen for `python` files. You can do this as follows.We have the following directory structure:
```ascii
nvim/
├── lua/
│ ├── after/ftplugin/
│ │ ├── python/
│ │ │ ├── init.lua -> always sourced.
│ │ │ ├── default.lua -> default settings.
│ │ │ └── myproject.lua -> specific settings.
... more files
```where the `lua/after` directory needs to be appended to the `runtimepath` using
the following command:```lua
vim.opt.rtp:append("lua/after")
```or when you use [lazy](www.github.com/folke/lazy.nvim) you should use the opts:
```lua
lazy.setup("plugins", { performance = { rtp = { paths = { "lua/after" } } } })
```now you can add the following to the `init.lua` file:
```lua
require("projectrc").require("after.ftplugin.python").setup()
```make sure you wrap your configuration in a function as all files in a filetype
directory are sourced, as is explained in `:h ftplugin`:```lua
local M = {}M.setup = function()
-- your configuration here
endreturn M
```Now the following will happen:
- Set your `PROJECTRC` to `myproject`.
- Open a python file.
- The `after/ftplugin/python/init.lua` file will always be sourced.
- It will try to source `after/ftplugin/python/myproject.lua`, and this file
exists. It will return a table with the `setup` function.
- You call the `setup` function, which will set your configuration.# Configuration
The plugin can be configured on a global level but also on a function level.
### Global configuration
The following global configuration options are available with their defaults:
```lua
require("projectrc").setup({
-- The name of the environment variable that holds the project identifier.
env = "PROJECTRC",
-- The name of the file that is sourced when the project config is not found.
fallback_file = "default.lua",
-- The value that is returned when the `fallback_file` is not found.
fallback_value = nil,
-- Callback function that is called when the project config is not found.
-- It must take the following tree arguments:
-- - parent: the parent directory of the project config.
-- - fallback_file: the name of the file to source, e.g., "default".
-- - fallback_value: the value to return when the fallback file cannot be
-- sourced.
-- Note that the last two arguments can be configured using the options
-- above.
callback = require("projectrc").try_require
})
```The `callback` needs some extra explanation. By the default, the
`require("projectrc").try_require` function is used. However, you can replace
this one with any function you like, as long as adheres to the following
signature:```lua
function(opts.fallback_file, opts.fallback_value)
-- Your custom logic here.
end
```For example, if you want to avoid sourcing the `fallback_file` for some specific
project, you can do the following:```lua
local function callback(...)
local prc = require("projectrc")
if prc.get_name() ~= "myproject" then
return prc.try_require(...)
end
end
```### Function level configuration
Lastly, you can use the options discussed above to configure the behavior of
only 1 function call to `require("projectrc").require`. This function accepts
the same `opts` table that is passed to `setup`. For example:```lua
require("projectrc").require("config.lsp", {
fallback_file = "foo",
fallback_value = {}
})
```which will source the file `config/lsp/foo.lua` and return an empty table if
this file does not exist. This only applies to this specific function call.# Troubleshooting
If you encounter any issues, please report them on the issue tracker at:
[projectrc issues](https://github.com/BartSte/nvim-projectrc/issues)# Contributing
Contributions are welcome! Please see [CONTRIBUTING](./CONTRIBUTING.md) for
more information.# License
Distributed under the [MIT License](./LICENCE).