commit e2cff543d603d58abbde0d2ab284ce45e0bd2dda Author: Jiří Štefka Date: Wed Mar 6 02:24:31 2024 +0100 Initial commit diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..a1d3540 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake . -Lv diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..63b3a63 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: mrcjkb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a8b6a5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +result +.direnv +.luarc.json diff --git a/.stylua.toml b/.stylua.toml new file mode 100644 index 0000000..4fe0607 --- /dev/null +++ b/.stylua.toml @@ -0,0 +1,6 @@ +line_endings = "Unix" +indent_type = "Spaces" +indent_width = 2 +quote_style = "AutoPreferSingle" +call_parentheses = "NoSingleTable" +# collapse_simple_statement = "Never" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee26526 --- /dev/null +++ b/README.md @@ -0,0 +1,300 @@ + +
+
+ + kickstart-nix.nvim + + + + + + + + + + + + + + +

❄️

+

+ + A dead simple Nix flake template repository
+ for Neovim +
+

+
+ + +[![Neovim][neovim-shield]][neovim-url] +[![Nix][nix-shield]][nix-url] +[![Lua][lua-shield]][lua-url] + +[![GPL2 License][license-shield]][license-url] +[![Issues][issues-shield]][issues-url] + +![](https://github.com/mrcjkb/kickstart-nix.nvim/assets/12857160/84faa268-82de-4401-acf3-efddc26dd58a) + +If Nix and Neovim have one thing in common, +it's that many new users don't know where to get started. +Most Nix-based Neovim setups assume deep expertise in both realms, +abstracting away Neovim's core functionalities +as well as the Nix internals used to build a Neovim config. +Frameworks and module-based DSLs are opinionated and difficult to diverge from +with one's own modifications. + +`kickstart-nix.nvim` is different: +It's geared for users of all levels, +making the migration of Neovim configurations to Nix straightforward. +This project aims to be as simple as possible, while allowing +for maximum flexibility. + +> [!NOTE] +> +> Similar to [`kickstart.nvim`](https://github.com/nvim-lua/kickstart.nvim), +> this repository is meant to be used by **you** to begin your +> **Nix**/Neovim journey; remove the things you don't use and add what you miss. + +## Quick Links + +- [Philosophy](#philosophy) +- [Features](#features) +- [Test drive](#test-drive) +- [Usage](#usage) +- [Installation](#installation) +- [Design](#design) +- [Pre-configured plugins](#pre-configured-plugins) +- [Syncing updates](#syncing-updates) +- [Alternative / similar projects](#alternative--similar-projects) + +## Philosophy + +- KISS principle with sane defaults. +- Manage plugins + external dependencies using Nix + (managing plugins shouldn't be the responsibility of a plugin). +- Configuration entirely in Lua[^1] (Vimscript is also possible). + This makes it easy to migrate from non-nix dotfiles. +- Use Neovim's built-in loading mechanisms. See: + - [`:h initialization`](https://neovim.io/doc/user/starting.html#initialization) + - [`:h runtimepath`](https://neovim.io/doc/user/options.html#'runtimepath') + - [`:h packadd`](https://neovim.io/doc/user/repeat.html#%3Apackadd) +- Use Neovim's built-in LSP client, with Nix managing language servers. + +## Features + +- Use either nixpkgs or flake inputs as plugin sources. +- Usable on any device with Neovim and Nix installed. +- Ability to create multiple derivations with different sets of plugins, + and simple regex filters to exclude config files. +- Uses Nix to generate a `.luarc.json` in the devShell's `shellHook`. + This sets up lua-language-server to recognize all plugins + and the Neovim API. + +[^1]: The absence of a Nix module DSL for Neovim configuration is deliberate. + If you were to copy the `nvim` directory to `$XDG_CONFIG_HOME`, + and install the plugins, it would work out of the box. + +## Test drive + +If you have Nix installed (with [flakes](https://nixos.wiki/wiki/Flakes) enabled), +you can test drive this by running: + +```console +nix run "github:mrcjkb/kickstart-nix.nvim" +``` + +## Usage + +1. Click on [Use this template](https://github.com/mrcjkb/kickstart-nix.nvim/generate) +to start a repo based on this template. **Do _not_ fork it**. +1. Add/remove plugins to/from the [Neovim overlay](./nix/neovim-overlay.nix). +1. Add/remove plugin configs to/from the `nvim/plugin` directory. +1. Modify as you wish (you will probably want to add a color theme, ...). + See: [Design](#design). +1. You can create more than one package using the `mkNeovim` function by + - Passing different plugin lists. + - Adding `ignoreConfigRegexes` (e.g. `= [ "^ftplugin/.*.lua" ]`). + +> [!TIP] +> +> The nix and lua files contain comments explaining +> what everything does in detail. + +## Installation + +### NixOS (with flakes) + +1. Add your flake to you NixOS flake inputs. +1. Add the overlay provided by this flake. + +```nix +nixpkgs.overlays = [ + # replace with the name you chose + .overlays.default +]; +``` + +You can then add the overlay's output(s) to the `systemPackages`: + +```nix +environment.systemPackages = with pkgs; [ + nvim-pkg # The default package added by the overlay +]; +``` + +### Non-NixOS + +With Nix installed (flakes enabled), from the repo root: + +```console +nix profile install .#nvim +``` + +## Design + +Directory structure: + +```sh +── flake.nix +── nvim # Neovim configs (lua), equivalent to ~/.config/nvim +── nix # Nix configs +``` + +### Neovim configs + +- Set options in `init.lua`. +- Source autocommands, user commands, keymaps, + and configure plugins in individual files within the `plugin` directory. +- Filetype-specific scripts (e.g. start LSP clients) in the `ftplugin` directory. +- Library modules in the `lua/user` directory. + +Directory structure: + +```sh +── nvim + ├── ftplugin # Sourced when opening a file type + │ └── .lua + ├── init.lua # Always sourced + ├── lua # Shared library modules + │ └── user + │ └── .lua + ├── plugin # Automatically sourced at startup + │ ├── autocommands.lua + │ ├── commands.lua + │ ├── keymaps.lua + │ ├── plugins.lua # Plugins that require a `setup` call + │ └── .lua # Plugin configurations + └── after # Empty in this template + ├── plugin # Sourced at the very end of startup (rarely needed) + └── ftplugin # Sourced when opening a filetype, after sourcing ftplugin scripts +``` + +> [!IMPORTANT] +> +> - Configuration variables (e.g. `vim.g.`) should go in `nvim/init.lua` +> or a module that is `require`d in `init.lua`. +> - Configurations for plugins that require explicit initialization +> (e.g. via a call to a `setup()` function) should go in `nvim/plugin/.lua` +> or `nvim/plugin/plugins.lua`. +> - See [Initialization order](#initialization-order) for details. + +### Nix + +You can declare Neovim derivations in `nix/neovim-overlay.nix`. + +There are two ways to add plugins: + +- The traditional way, using `nixpkgs` as the source. +- By adding plugins as flake inputs (if you like living on the bleeding-edge). + Plugins added as flake inputs must be built in `nix/plugin-overlay.nix`. + +Directory structure: + +```sh +── flake.nix +── nix + ├── mkNeovim.nix # Function for creating the Neovim derivation + └── neovim-overlay.nix # Overlay that adds Neovim derivation +``` + +### Initialization order + +This derivation creates an `init.lua` as follows: + +1. Add `nvim/lua` to the `runtimepath`. +1. Add the content of `nvim/init.lua`. +1. Add `nvim/*` to the `runtimepath`. +1. Add `nvim/after` to the `runtimepath`. + +This means that modules in `nvim/lua` can be `require`d in `init.lua` and `nvim/*/*.lua`. + +Modules in `nvim/plugin/` are sourced automatically, as if they were plugins. +Because they are added to the runtime path at the end of the resulting `init.lua`, +Neovim sources them _after_ loading plugins. + +## Pre-configured plugins + +This configuration comes with [a few plugins pre-configured](./nix/neovim-overlay.nix). + +You can add or remove plugins by + +- Adding/Removing them in the [Nix list](./nix/neovim-overlay.nix). +- Adding/Removing the config in `nvim/plugin/.lua`. + +## Syncing updates + +If you have used this template and would like to fetch updates +that were added later... + +Add this template as a remote: + +```console +git remote add upstream git@github.com:mrcjkb/kickstart-nix.nvim.git +``` + +Fetch and merge changes: + +```console +git fetch upstream +git merge upstream/main --allow-unrelated-histories +``` + +## Alternative / similar projects + +- [`kickstart.nvim`](https://github.com/nvim-lua/kickstart.nvim): + Single-file Neovim configuration template with a similar philosophy to this project. + Does not use Nix to manage plugins. +- [`neovim-flake`](https://github.com/jordanisaacs/neovim-flake): + Configured using a Nix module DSL. +- [`NixVim`](https://github.com/nix-community/nixvim): + A Neovim distribution configured using a NixOS module. +- [`nixCats-nvim`](https://github.com/BirdeeHub/nixCats-nvim): + A project that organises plugins into categories. + It also separates lua and nix configuration. +- [`lazy-nix-helper.nvim`](https://github.com/b-src/lazy-nix-helper.nvim): + For lazy.nvim users who would like to manage plugins with Nix, + but load them with lazy.nvim. + +> [!NOTE] +> +> When comparing with projects in the "non-Nix world", this +> repository would be more comparable to `kickstart.nvim` (hence the name), +> while the philosophies of `neovim-flake` and `NixVim` are more in line with +> a Neovim distribution like [`LunarVim`](https://www.lunarvim.org/) +> or [`LazyVim`](https://www.lazyvim.org/) +> (though they are more minimal by default). + + +[neovim-shield]: https://img.shields.io/badge/NeoVim-%2357A143.svg?&style=for-the-badge&logo=neovim&logoColor=white +[neovim-url]: https://neovim.io/ +[nix-shield]: https://img.shields.io/badge/nix-0175C2?style=for-the-badge&logo=NixOS&logoColor=white +[nix-url]: https://nixos.org/ +[lua-shield]: https://img.shields.io/badge/lua-%232C2D72.svg?style=for-the-badge&logo=lua&logoColor=white +[lua-url]: https://www.lua.org/ +[license-shield]: https://img.shields.io/github/license/mrcjkb/kickstart-nix.nvim.svg?style=for-the-badge +[license-url]: https://github.com/mrcjkb/kickstart-nix.nvim/blob/master/LICENSE +[issues-shield]: https://img.shields.io/github/issues/mrcjkb/kickstart-nix.nvim.svg?style=for-the-badge +[issues-url]: https://github.com/mrcjkb/kickstart-nix.nvim/issues +[license-shield]: https://img.shields.io/github/license/mrcjkb/kickstart-nix.nvim.svg?style=for-the-badge +[license-url]: https://github.com/mrcjkb/kickstart-nix.nvim/blob/master/LICENSE diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f490a4a --- /dev/null +++ b/flake.lock @@ -0,0 +1,133 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1706830856, + "narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gen-luarc": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1708639673, + "narHash": "sha256-ZnwAKUm7wLalSdr1wdihYTODql0OD6HAxgWJKweu7Hk=", + "owner": "mrcjkb", + "repo": "nix-gen-luarc-json", + "rev": "6c5c893f0d1534dccafedaaf3ad1cf2968704a2e", + "type": "github" + }, + "original": { + "owner": "mrcjkb", + "repo": "nix-gen-luarc-json", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1708475490, + "narHash": "sha256-g1v0TsWBQPX97ziznfJdWhgMyMGtoBFs102xSYO4syU=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "0e74ca98a74bc7270d28838369593635a5db3260", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1706550542, + "narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "97b17f32362e475016f942bbdfda4a4a72a8a652", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1708475490, + "narHash": "sha256-g1v0TsWBQPX97ziznfJdWhgMyMGtoBFs102xSYO4syU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0e74ca98a74bc7270d28838369593635a5db3260", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "gen-luarc": "gen-luarc", + "nixpkgs": "nixpkgs_2" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..7f03010 --- /dev/null +++ b/flake.nix @@ -0,0 +1,73 @@ +{ + description = "Neovim derivation"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + gen-luarc.url = "github:mrcjkb/nix-gen-luarc-json"; + + # Add bleeding-edge plugins here. + # They can be updated with `nix flake update` (make sure to commit the generated flake.lock) + # wf-nvim = { + # url = "github:Cassin01/wf.nvim"; + # flake = false; + # }; + }; + + outputs = inputs @ { + self, + nixpkgs, + flake-utils, + gen-luarc, + ... + }: let + supportedSystems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + + # This is where the Neovim derivation is built. + neovim-overlay = import ./nix/neovim-overlay.nix {inherit inputs;}; + in + flake-utils.lib.eachSystem supportedSystems (system: let + pkgs = import nixpkgs { + inherit system; + overlays = [ + # Import the overlay, so that the final Neovim derivation(s) can be accessed via pkgs. + neovim-overlay + # This adds a function can be used to generate a .luarc.json + # containing the Neovim API all plugins in the workspace directory. + # The generated file can be symlinked in the devShell's shellHook. + gen-luarc.overlays.default + ]; + }; + shell = pkgs.mkShell { + name = "nvim-devShell"; + buildInputs = with pkgs; [ + # Tools for Lua and Nix development, useful for editing files in this repo + lua-language-server + nil + stylua + luajitPackages.luacheck + ]; + shellHook = '' + # symlink the .luarc.json generated in the overlay + ln -fs ${pkgs.nvim-luarc-json} .luarc.json + ''; + }; + in { + packages = rec { + default = nvim; + nvim = pkgs.nvim-pkg; + }; + devShells = { + default = shell; + }; + }) + // { + # You can add this overlay to your NixOS configuration + overlays.default = neovim-overlay; + }; +} diff --git a/nix/mkNeovim.nix b/nix/mkNeovim.nix new file mode 100644 index 0000000..2b64c00 --- /dev/null +++ b/nix/mkNeovim.nix @@ -0,0 +1,182 @@ +# Function for creating a Neovim derivation +{ + pkgs, + lib, + stdenv, +}: +with lib; + { + appName ? null, # NVIM_APPNAME - Defaults to 'nvim' + plugins ? [], # List of plugins + # List of dev plugins (will be bootstrapped) - useful for plugin developers + # { name = ; url = ; } + devPlugins ? [], + # Regexes for config files to ignore, relative to the nvim directory. + # e.g. [ "^plugin/neogit.lua" "^ftplugin/.*.lua" ] + ignoreConfigRegexes ? [], + extraPackages ? [], # Extra runtime dependencies (e.g. ripgrep, ...) + # The below arguments can typically be left as their defaults + resolvedExtraLuaPackages ? [], # Additional lua packages (not plugins), e.g. from luarocks.org + extraPython3Packages ? p: [], # Additional python 3 packages + withPython3 ? true, # Build Neovim with Python 3 support? + withRuby ? false, # Build Neovim with Ruby support? + withNodeJs ? false, # Build Neovim with NodeJS support? + withSqlite ? true, # Add sqlite? This is a dependency for some plugins + # You probably don't want to create vi or vim aliases + # if the appName is something different than "nvim" + viAlias ? appName == "nvim", # Add a "vi" binary to the build output as an alias? + vimAlias ? appName == "nvim", # Add a "vim" binary to the build output as an alias? + }: let + # This is the structure of a plugin definition. + # Each plugin in the `plugins` argument list can also be defined as this attrset + defaultPlugin = { + plugin = null; # e.g. nvim-lspconfig + config = null; # plugin config + # If `optional` is set to `false`, the plugin is installed in the 'start' packpath + # set to `true`, it is installed in the 'opt' packpath, and can be lazy loaded with + # ':packadd! {plugin-name} + optional = false; + runtime = {}; + }; + + externalPackages = extraPackages ++ (optionals withSqlite [pkgs.sqlite]); + + # Map all plugins to an attrset { plugin = ; config = ; optional = ; ... } + normalizedPlugins = map (x: + defaultPlugin + // ( + if x ? plugin + then x + else {plugin = x;} + )) + plugins; + + # This nixpkgs util function creates an attrset + # that pkgs.wrapNeovimUnstable uses to configure the Neovim build. + neovimConfig = pkgs.neovimUtils.makeNeovimConfig { + inherit extraPython3Packages withPython3 withRuby withNodeJs viAlias vimAlias; + plugins = normalizedPlugins; + }; + + # This uses the ignoreConfigRegexes list to filter + # the nvim directory + nvimRtpSrc = let + src = ../nvim; + in + lib.cleanSourceWith { + inherit src; + name = "nvim-rtp-src"; + filter = path: tyoe: let + srcPrefix = toString src + "/"; + relPath = lib.removePrefix srcPrefix (toString path); + in + lib.all (regex: builtins.match regex relPath == null) ignoreConfigRegexes; + }; + + # Split runtimepath into 3 directories: + # - lua, to be prepended to the rtp at the beginning of init.lua + # - nvim, containing plugin, ftplugin, ... subdirectories + # - after, to be sourced last in the startup initialization + # See also: https://neovim.io/doc/user/starting.html + nvimRtp = stdenv.mkDerivation { + name = "nvim-rtp"; + src = nvimRtpSrc; + + buildPhase = '' + mkdir -p $out/nvim + mkdir -p $out/lua + rm init.lua + ''; + + installPhase = '' + cp -r after $out/after + rm -r after + cp -r lua $out/lua + rm -r lua + cp -r * $out/nvim + ''; + }; + + # The final init.lua content that we pass to the Neovim wrapper. + # It wraps the user init.lua, prepends the lua lib directory to the RTP + # and appends the nvim and after directory to the RTP + # It also adds logic for bootstrapping dev plugins (for plugin developers) + initLua = + '' + vim.loader.enable() + -- prepend lua directory + vim.opt.rtp:prepend('${nvimRtp}/lua') + '' + # Wrap init.lua + + (builtins.readFile ../nvim/init.lua) + # Bootstrap/load dev plugins + + optionalString (devPlugins != []) ( + '' + local dev_pack_path = vim.fn.stdpath('data') .. '/site/pack/dev' + local dev_plugins_dir = dev_pack_path .. '/opt' + local dev_plugin_path + '' + + strings.concatMapStringsSep + "\n" + (plugin: '' + dev_plugin_path = dev_plugins_dir .. '/${plugin.name}' + if vim.fn.empty(vim.fn.glob(dev_plugin_path)) > 0 then + vim.notify('Bootstrapping dev plugin ${plugin.name} ...', vim.log.levels.INFO) + vim.cmd('!${pkgs.git}/bin/git clone ${plugin.url} ' .. dev_plugin_path) + end + vim.cmd('packadd! ${plugin.name}') + '') + devPlugins + ) + # Append nvim and after directories to the runtimepath + + '' + vim.opt.rtp:append('${nvimRtp}/nvim') + vim.opt.rtp:append('${nvimRtp}/after') + ''; + + # Add arguments to the Neovim wrapper script + extraMakeWrapperArgs = builtins.concatStringsSep " " ( + # Set the NVIM_APPNAME environment variable + (optional (appName != "nvim" && appName != null && appName != "") + ''--set NVIM_APPNAME "${appName}"'') + # Add external packages to the PATH + ++ (optional (externalPackages != []) + ''--prefix PATH : "${makeBinPath externalPackages}"'') + # Set the LIBSQLITE_CLIB_PATH if sqlite is enabled + ++ (optional withSqlite + ''--set LIBSQLITE_CLIB_PATH "${pkgs.sqlite.out}/lib/libsqlite3.so"'') + # Set the LIBSQLITE environment variable if sqlite is enabled + ++ (optional withSqlite + ''--set LIBSQLITE "${pkgs.sqlite.out}/lib/libsqlite3.so"'') + ); + + # Native Lua libraries + extraMakeWrapperLuaCArgs = optionalString (resolvedExtraLuaPackages != []) '' + --suffix LUA_CPATH ";" "${ + lib.concatMapStringsSep ";" pkgs.luaPackages.getLuaCPath + resolvedExtraLuaPackages + }"''; + + # Lua libraries + extraMakeWrapperLuaArgs = + optionalString (resolvedExtraLuaPackages != []) + '' + --suffix LUA_PATH ";" "${ + concatMapStringsSep ";" pkgs.luaPackages.getLuaPath + resolvedExtraLuaPackages + }"''; + in + # wrapNeovimUnstable is the nixpkgs utility function for building a Neovim derivation. + pkgs.wrapNeovimUnstable pkgs.neovim-unwrapped (neovimConfig + // { + luaRcContent = initLua; + wrapperArgs = + escapeShellArgs neovimConfig.wrapperArgs + + " " + + extraMakeWrapperArgs + + " " + + extraMakeWrapperLuaCArgs + + " " + + extraMakeWrapperLuaArgs; + wrapRc = true; + }) diff --git a/nix/neovim-overlay.nix b/nix/neovim-overlay.nix new file mode 100644 index 0000000..425d5be --- /dev/null +++ b/nix/neovim-overlay.nix @@ -0,0 +1,114 @@ +# This overlay, when applied to nixpkgs, adds the final neovim derivation to nixpkgs. +{inputs}: final: prev: +with final.pkgs.lib; let + pkgs = final; + + # Use this to create a plugin from a flake input + mkNvimPlugin = src: pname: + pkgs.vimUtils.buildVimPlugin { + inherit pname src; + version = src.lastModifiedDate; + }; + + # This is the helper function that builds the Neovim derivation. + mkNeovim = pkgs.callPackage ./mkNeovim.nix {}; + + # A plugin can either be a package or an attrset, such as + # { plugin = ; # the package, e.g. pkgs.vimPlugins.nvim-cmp + # config = ; # String; a config that will be loaded with the plugin + # # Boolean; Whether to automatically load the plugin as a 'start' plugin, + # # or as an 'opt' plugin, that can be loaded with `:packadd!` + # optional = ; # Default: false + # ... + # } + all-plugins = with pkgs.vimPlugins; [ + # plugins from nixpkgs go in here. + # https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=vimPlugins + nvim-treesitter.withAllGrammars + luasnip # snippets | https://github.com/l3mon4d3/luasnip/ + # nvim-cmp (autocompletion) and extensions + nvim-cmp # https://github.com/hrsh7th/nvim-cmp + cmp_luasnip # snippets autocompletion extension for nvim-cmp | https://github.com/saadparwaiz1/cmp_luasnip/ + lspkind-nvim # vscode-like LSP pictograms | https://github.com/onsails/lspkind.nvim/ + cmp-nvim-lsp # LSP as completion source | https://github.com/hrsh7th/cmp-nvim-lsp/ + cmp-nvim-lsp-signature-help # https://github.com/hrsh7th/cmp-nvim-lsp-signature-help/ + cmp-buffer # current buffer as completion source | https://github.com/hrsh7th/cmp-buffer/ + cmp-path # file paths as completion source | https://github.com/hrsh7th/cmp-path/ + cmp-nvim-lua # neovim lua API as completion source | https://github.com/hrsh7th/cmp-nvim-lua/ + cmp-cmdline # cmp command line suggestions + cmp-cmdline-history # cmp command line history suggestions + # ^ nvim-cmp extensions + # git integration plugins + diffview-nvim # https://github.com/sindrets/diffview.nvim/ + neogit # https://github.com/TimUntersberger/neogit/ + gitsigns-nvim # https://github.com/lewis6991/gitsigns.nvim/ + vim-fugitive # https://github.com/tpope/vim-fugitive/ + # ^ git integration plugins + # telescope and extensions + telescope-nvim # https://github.com/nvim-telescope/telescope.nvim/ + telescope-fzy-native-nvim # https://github.com/nvim-telescope/telescope-fzy-native.nvim + # telescope-smart-history-nvim # https://github.com/nvim-telescope/telescope-smart-history.nvim + # ^ telescope and extensions + # UI + lualine-nvim # Status line | https://github.com/nvim-lualine/lualine.nvim/ + nvim-navic # Add LSP location to lualine | https://github.com/SmiteshP/nvim-navic + statuscol-nvim # Status column | https://github.com/luukvbaal/statuscol.nvim/ + nvim-treesitter-context # nvim-treesitter-context + # ^ UI + # language support + # ^ language support + # navigation/editing enhancement plugins + vim-unimpaired # predefined ] and [ navigation keymaps | https://github.com/tpope/vim-unimpaired/ + eyeliner-nvim # Highlights unique characters for f/F and t/T motions | https://github.com/jinh0/eyeliner.nvim + nvim-surround # https://github.com/kylechui/nvim-surround/ + nvim-treesitter-textobjects # https://github.com/nvim-treesitter/nvim-treesitter-textobjects/ + nvim-ts-context-commentstring # https://github.com/joosepalviste/nvim-ts-context-commentstring/ + # ^ navigation/editing enhancement plugins + # Useful utilities + nvim-unception # Prevent nested neovim sessions | nvim-unception + # ^ Useful utilities + # libraries that other plugins depend on + sqlite-lua + plenary-nvim + nvim-web-devicons + vim-repeat + # ^ libraries that other plugins depend on + # bleeding-edge plugins from flake inputs + # (mkNvimPlugin inputs.wf-nvim "wf.nvim") # (example) keymap hints | https://github.com/Cassin01/wf.nvim + # ^ bleeding-edge plugins from flake inputs + which-key-nvim + ]; + + extraPackages = with pkgs; [ + # language servers, etc. + lua-language-server + nil # nix LSP + ]; +in { + # This is the neovim derivation + # returned by the overlay + nvim-pkg = mkNeovim { + plugins = all-plugins; + inherit extraPackages; + }; + + # This can be symlinked in the devShell's shellHook + nvim-luarc-json = final.mk-luarc-json { + plugins = all-plugins; + }; + + # You can add as many derivations as you like. + # Use `ignoreConfigRegexes` to filter out config + # files you would not like to include. + # + # For example: + # + # nvim-pkg-no-telescope = mkNeovim { + # plugins = []; + # ignoreConfigRegexes = [ + # "^plugin/telescope.lua" + # "^ftplugin/.*.lua" + # ]; + # inherit extraPackages; + # }; +} diff --git a/nvim-nix.svg b/nvim-nix.svg new file mode 100644 index 0000000..882567a --- /dev/null +++ b/nvim-nix.svg @@ -0,0 +1,317 @@ + + + + neovim-mark@2x + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + neovim-mark@2x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nvim/after/README.md b/nvim/after/README.md new file mode 100644 index 0000000..a4b4ff2 --- /dev/null +++ b/nvim/after/README.md @@ -0,0 +1,8 @@ +## `after` directory + +Scripts put in + +- `after/plugin` will be sourced *after* init.lua + or any other scripts are sourced during startup. +- `after/ftplugin` will be sourced when opening a + filetype, *after* any other `ftplugin` scripts are sourced. diff --git a/nvim/ftplugin/lua.lua b/nvim/ftplugin/lua.lua new file mode 100644 index 0000000..125c422 --- /dev/null +++ b/nvim/ftplugin/lua.lua @@ -0,0 +1,55 @@ +vim.bo.comments = ':---,:--' + +local lua_ls_cmd = 'lua-language-server' + +-- Check if lua-language-server is available +if vim.fn.executable(lua_ls_cmd) ~= 1 then + return +end + +local root_files = { + '.luarc.json', + '.luarc.jsonc', + '.luacheckrc', + '.stylua.toml', + 'stylua.toml', + 'selene.toml', + 'selene.yml', + '.git', +} + +vim.lsp.start { + name = 'luals', + cmd = { lua_ls_cmd }, + root_dir = vim.fs.dirname(vim.fs.find(root_files, { upward = true })[1]), + capabilities = require('user.lsp').make_client_capabilities(), + settings = { + Lua = { + runtime = { + version = 'LuaJIT', + }, + diagnostics = { + -- Get the language server to recognize the `vim` global, etc. + globals = { + 'vim', + 'describe', + 'it', + 'assert', + 'stub', + }, + disable = { + 'duplicate-set-field', + }, + }, + workspace = { + checkThirdParty = false, + }, + telemetry = { + enable = false, + }, + hint = { -- inlay hints (supported in Neovim >= 0.10) + enable = true, + }, + }, + }, +} diff --git a/nvim/ftplugin/nix.lua b/nvim/ftplugin/nix.lua new file mode 100644 index 0000000..8691e2a --- /dev/null +++ b/nvim/ftplugin/nix.lua @@ -0,0 +1,18 @@ +-- Exit if the language server isn't available +if vim.fn.executable('nil') ~= 1 then + return +end + +local root_files = { + 'flake.nix', + 'default.nix', + 'shell.nix', + '.git', +} + +vim.lsp.start { + name = 'nil_ls', + cmd = { 'nil' }, + root_dir = vim.fs.dirname(vim.fs.find(root_files, { upward = true })[1]), + capabilities = require('user.lsp').make_client_capabilities(), +} diff --git a/nvim/init.lua b/nvim/init.lua new file mode 100644 index 0000000..af08696 --- /dev/null +++ b/nvim/init.lua @@ -0,0 +1,115 @@ +local cmd = vim.cmd +local fn = vim.fn +local opt = vim.o +local g = vim.g + +-- key. Defaults to `\`. Some people prefer space. +-- g.mapleader = ' ' +-- g.maplocalleader = ' ' + +opt.compatible = false + +-- Enable true colour support +if fn.has('termguicolors') then + opt.termguicolors = true +end + +-- See :h