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/.gitignore b/.gitignore index e4f792f..a0a4ae3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -*.AppImage -squashfs-root result +*.AppImage +.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 index f7968a9..53d45fa 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,6 @@ This is a flake to build a Neovim package that includes my custom Lua config and ## Why the hell though? I use these AppImages because I develop in a number of airgapped environments that make traditional dotfile management a nightmare. Downloading a single AppImage and copying it around is a more suckless way of managing this. + +## kickstart-nix-nvim +This repo is based off https://github.com/nix-community/kickstart-nix.nvim diff --git a/config/ftplugin/nix.lua b/config/ftplugin/nix.lua deleted file mode 100644 index 3c844d9..0000000 --- a/config/ftplugin/nix.lua +++ /dev/null @@ -1 +0,0 @@ -vim.opt_local.tabstop = 2 diff --git a/config/init.lua b/config/init.lua deleted file mode 100644 index bda5e1f..0000000 --- a/config/init.lua +++ /dev/null @@ -1,350 +0,0 @@ --------------------- --- Mini --------------------- -require("mini-conf") - --------------------- --- Toggleterm --------------------- -require("toggleterm").setup{ - open_mapping = [[]], - direction = "float", - close_on_exit = true, -} - --------------------- --- Telescope --------------------- -local telescope = require("telescope.builtin") -vim.keymap.set("n", "", telescope.buffers, {noremap = true, silent = true}) -vim.keymap.set("n", "ff", telescope.find_files, {noremap = true, silent = true}) -vim.keymap.set("n", "fg", telescope.git_files, {noremap = true, silent = true}) -vim.keymap.set("n", "fc", telescope.command_history, {noremap = true, silent = true}) -vim.keymap.set("n", "fa", telescope.live_grep, {noremap = true, silent = true}) -vim.keymap.set("n", "f8", telescope.grep_string, {noremap = true, silent = true}) -vim.keymap.set("n", "fs", telescope.treesitter, {noremap = true, silent = true}) -vim.keymap.set("n", "fq", telescope.quickfix, {noremap = true, silent = true}) -vim.keymap.set("n", "fq", telescope.quickfix, {noremap = true, silent = true}) -vim.keymap.set("n", "f", telescope.resume, {noremap = true, silent = true}) - -local telescope = require("telescope") -telescope.setup({ - defaults = { - layout_strategy = "vertical", - layout_config = { width = .90, }, - prompt_title = false, - results_title = false, - preview_title = false, - vimgrep_arguments = { - "rg", - "--color=never", - "--no-heading", - "--hidden", - "--with-filename", - "--line-number", - "--column", - "--smart-case" - }, - mappings = { - i = { - ["wq"] = require("telescope.actions").close, - [""] = require("telescope.actions").close, - [""] = require("telescope.actions").move_selection_previous, - [""] = require("telescope.actions").move_selection_next, - }, - }, - }, -}) -telescope.load_extension("fzf") - --------------------- --- Treesitter --------------------- -require("nvim-treesitter.configs").setup { - ensure_installed = {}, - highlight = { - enable = true, - }, - indent = { - enable = true, - }, - textobjects = { - select = { - enable = true, - lookahead = true, - keymaps = { - ["af"] = "@function.outer", - ["if"] = "@function.inner", - ["aa"] = "@statement.outer", - ["ia"] = "@parameter.inner", - }, - }, - move = { - enable = true, - set_jumps = true, -- whether to set jumps in the jumplist - goto_next_start = { - [']]'] = '@function.outer', - [']a'] = '@parameter.inner', - }, - goto_previous_start = { - ['[['] = '@function.outer', - ['[a'] = '@parameter.inner', - }, - }, - swap = { - enable = true, - swap_next = { - ["s]"] = "@parameter.inner", - }, - swap_previous = { - ["s["] = "@parameter.inner", - }, - }, }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = '', - node_incremental = '', - node_decremental = '', - }, - }, -} - --------------------- --- LSP Config --------------------- - --- Setup language servers. -local lspconfig = require('lspconfig') -local capabilities = require('cmp_nvim_lsp').default_capabilities() -lspconfig.gopls.setup { on_attach = function(_, bufnr) - capabilities = capabilities - vim.api.nvim_command("au BufWritePre lua vim.lsp.buf.format { async = false }") -end -} -lspconfig.pyright.setup { capabilities = capabilities } -lspconfig.nil_ls.setup { capabilities = capabilities } - --- Global mappings. --- See `:help vim.diagnostic.*` for documentation on any of the below functions -vim.keymap.set('n', 'de', vim.diagnostic.open_float) -vim.keymap.set('n', '[d', vim.diagnostic.goto_prev) -vim.keymap.set('n', ']d', vim.diagnostic.goto_next) - -vim.diagnostic.config({ - virtual_text = true, - underline = true, - update_in_insert = false, -}) --- Use LspAttach autocommand to only map the following keys --- after the language server attaches to the current buffer -vim.api.nvim_create_autocmd('LspAttach', { - group = vim.api.nvim_create_augroup('UserLspConfig', {}), - callback = function(ev) - -- Enable completion triggered by - vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc' - -- Buffer local mappings. - -- See `:help vim.lsp.*` for documentation on any of the below functions - local opts = { buffer = ev.buf } - vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts) - vim.keymap.set('n', 'rn', vim.lsp.buf.rename, opts) - vim.keymap.set({ 'n', 'v' }, 'da', vim.lsp.buf.code_action, opts) - vim.keymap.set("n", "dd", "Telescope lsp_definitions", { buffer = bufnr }) - vim.keymap.set("n", "di", "Telescope lsp_implementations", { buffer = bufnr }) - vim.keymap.set("n", "dr", "Telescope lsp_references", { buffer = bufnr }) - vim.keymap.set("n", "dt", "Telescope lsp_type_definitions", { buffer = bufnr }) - vim.keymap.set("n", "ds", "Telescope lsp_document_symbols", { buffer = bufnr }) - vim.keymap.set('n', 'dl', vim.lsp.codelens.run) - vim.keymap.set('n', 'dg', vim.diagnostic.setqflist) - vim.keymap.set('n', 'df', function() - vim.lsp.buf.format { async = true } - end, opts) - end, -}) - --------------------- --- Git --------------------- -require('gitsigns').setup{ - signcolumn = false, - numhl = true, - on_attach = function() - local gs = package.loaded.gitsigns - vim.keymap.set("n", "gg", gs.preview_hunk) - vim.keymap.set('n', 'gb', function() gs.blame_line{full=true} end) - vim.keymap.set('n', 'gr', gs.reset_hunk) - vim.keymap.set('v', 'gr', function() gs.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end) - -- Navigation - vim.keymap.set('n', ']g', function() - if vim.wo.diff then return ']c' end - vim.schedule(function() gs.next_hunk() end) - return '' - end, {expr=true}) - - vim.keymap.set('n', '[g', function() - if vim.wo.diff then return '[c' end - vim.schedule(function() gs.prev_hunk() end) - return '' - end, {expr=true}) - end -} - -require("diffview").setup({ - use_icons = false, -}) - -local neogit = require('neogit') -neogit.setup {integrations = {diffview = true}} -vim.keymap.set('n', 'ng', neogit.open) - --------------------- --- Oil & Undo --------------------- -local oil = require('oil') -oil.setup({ - watch_for_changes = true, - columns = { - "permissions", - "size" - }, - view_options = { - show_hidden = true - }, - keymaps = { - ["wq"] = "actions.close" - } -}) -vim.keymap.set("n", "c", oil.toggle_float, {noremap = true, silent = true}); -vim.keymap.set("n", "u", "UndotreeToggle") -vim.g.undotree_ShortIndicators = 1 -vim.g.undotree_SetFocusWhenToggle = 1 - --------------------- --- Aerial --------------------- -require("aerial").setup({ - default_direction = "prefer_left", - autojump = true, - on_attach = function(bufnr) - vim.keymap.set("n", "{", "AerialPrev", { buffer = bufnr }) - vim.keymap.set("n", "}", "AerialNext", { buffer = bufnr }) - end, -}) -vim.keymap.set("n", "aa", "AerialToggle!") - - ---- --------------------- --- Refactoring --------------------- -require('refactoring').setup({ - prompt_func_return_type = { go = true, }, - prompt_func_param_type = { go = true, }, - show_success_message = true, -}) - -require("telescope").load_extension("refactoring") -vim.keymap.set( - {"n"}, - "rr", - function() require('telescope').extensions.refactoring.refactors() end -) --------------------- --- Colors --------------------- - -require("rose-pine").setup({ - variant = "moon", - styles = { - bold = false, - italic = false, - transparency = true, - }, -}) -vim.cmd.colorscheme "rose-pine-main" - --------------------- --- Neogen --------------------- -require("neogen").setup{} -vim.keymap.set("n","nd", "Neogen", {noremap = true, silent = true}) - --------------------- ----Completion --------------------- -local cmp = require'cmp' - -cmp.setup({ - snippet = { - expand = function(args) - require('luasnip').lsp_expand(args.body) - end, - }, - mapping = cmp.mapping.preset.insert({ - [''] = cmp.mapping.scroll_docs(-4), - [''] = cmp.mapping.scroll_docs(4), - [''] = cmp.mapping.complete(), - ['q'] = cmp.mapping.abort(), - [''] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. - }), - sources = cmp.config.sources({ - { name = 'nvim_lsp' }, - { name = 'luasnip' }, - }, { - { name = 'buffer' }, - }) -}) - -cmp.setup.cmdline({ '/', '?' }, { - mapping = cmp.mapping.preset.cmdline(), - sources = { - { name = 'buffer' } - } -}) - -cmp.setup.cmdline(':', { - mapping = cmp.mapping.preset.cmdline(), - sources = cmp.config.sources({ - { name = 'path' } - }, { - { name = 'cmdline' } - }), - matching = { disallow_symbol_nonprefix_matching = false } -}) - --------------------- --- Luasnip --------------------- -local ls = require("luasnip") -ls.config.set_config { - history = true, - updateevents = "TextChanged, TextChangedI", -} -require("luasnip.loaders.from_vscode").lazy_load() - -vim.keymap.set({"i", "s"}, "", function() - if ls.expand_or_jumpable() then - ls.expand_or_jump() - end -end, {silent = true}) - -vim.keymap.set({"i", "s"}, "", function() - if ls.jumpable(-1) then - ls.jump(-1) - end -end, {silent = true}) - -vim.keymap.set({"i", "s"}, "", function() - if ls.choice_active() then - ls.change_choice(1) - end -end, {silent = true}) - --------------------- --- Snippets --------------------- -require("snippets") --------------------- --- include our config last to override --------------------- -require("nvim-conf") diff --git a/config/lua/snippets.lua b/config/lua/snippets.lua deleted file mode 100644 index 1a55309..0000000 --- a/config/lua/snippets.lua +++ /dev/null @@ -1,6 +0,0 @@ -local ls = require "luasnip" - -local fmta = require("luasnip.extras.fmt").fmta -ls.add_snippets("go", { - ls.snippet("ie", fmta("if err != nil {\n\treturn \n}", { err = ls.insert_node(1, "err") })), -}) diff --git a/flake.lock b/flake.lock index 8d33b83..e72b4c6 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,23 @@ { "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1717285511, + "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -18,18 +36,65 @@ "type": "github" } }, + "gen-luarc": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1718922730, + "narHash": "sha256-ykhhOPqA9NzdNBr3ii+3h2DkK2+wasNqQLfMF6BXxTE=", + "owner": "mrcjkb", + "repo": "nix-gen-luarc-json", + "rev": "021e8078e43884c6cdc70ca753d9a0b146cd55a4", + "type": "github" + }, + "original": { + "owner": "mrcjkb", + "repo": "nix-gen-luarc-json", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1723019560, - "narHash": "sha256-O/kxmybNecC3Efr6ITOdtCzFv90/B2Iiedavj5aRWt0=", + "lastModified": 1718714799, + "narHash": "sha256-FUZpz9rg3gL8NVPKbqU8ei1VkPLsTIfAJ2fdAf5qjak=", "owner": "nixos", "repo": "nixpkgs", - "rev": "f5129fb42b9c262318130a97b47516946da3e7d7", + "rev": "c00d587b1a1afbf200b1d8f0b0e4ba9deb1c7f0e", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixpkgs-unstable", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1717284937, + "narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1723175592, + "narHash": "sha256-M0xJ3FbDUc4fRZ84dPGx5VvgFsOzds77KiBMW/mMTnI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5e0ca22929f3342b19569b21b2f3462f053e497b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } @@ -37,7 +102,8 @@ "root": { "inputs": { "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "gen-luarc": "gen-luarc", + "nixpkgs": "nixpkgs_2" } }, "systems": { diff --git a/flake.nix b/flake.nix index 8733756..36a10c5 100644 --- a/flake.nix +++ b/flake.nix @@ -1,65 +1,64 @@ { - description = "..."; + description = "Neovim derivation"; + inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + 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 = {self, nixpkgs, flake-utils, ...}: - flake-utils.lib.eachDefaultSystem (system: let - recursiveMerge = attrList: let - f = attrPath: - builtins.zipAttrsWith (n: values: - if pkgs.lib.tail values == [] - then pkgs.lib.head values - else if pkgs.lib.all pkgs.lib.isList values - then pkgs.lib.unique (pkgs.lib.concatLists values) - else if pkgs.lib.all pkgs.lib.isAttrs values - then f (attrPath ++ [n]) values - else pkgs.lib.last values); - in - f [] attrList; + + outputs = inputs @ { + self, + nixpkgs, + flake-utils, + gen-luarc, + ... + }: let + supportedSystems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + neovim-overlay = import ./nix/neovim-overlay.nix {inherit inputs;}; + in + flake-utils.lib.eachSystem supportedSystems (system: let pkgs = import nixpkgs { inherit system; + overlays = [ + neovim-overlay + gen-luarc.overlays.default + ]; }; - plugins = import ./plugins.nix { - inherit pkgs; + shell = pkgs.mkShell { + name = "nvim-devShell"; + buildInputs = with pkgs; [ + lua-language-server + nil + stylua + luajitPackages.luacheck + ]; + shellHook = '' + ln -fs ${pkgs.nvim-luarc-json} .luarc.json + ''; }; - dependencies = with pkgs; [ - ripgrep - gopls - pyright - nil - ]; - neovim-with-deps = recursiveMerge [ - pkgs.neovim-unwrapped - { buildInputs = dependencies; } - ]; - baseRC = '' - lua << EOF - package.path = "${self}/config/?.lua;" .. "${self}/config/lua/?.lua;" .. package.path - vim.o.runtimepath = "${self}/config," .. vim.o.runtimepath - ''; - in rec { - packages.neovim = pkgs.wrapNeovim neovim-with-deps ({ - viAlias = false; - vimAlias = true; - withRuby = false; - withPython3 = false; - extraMakeWrapperArgs = ''--prefix PATH : "${pkgs.lib.makeBinPath dependencies}"''; - configure = { - customRC = - baseRC - + pkgs.lib.readFile ./config/init.lua - + ''EOF''; - packages.plugins = { - start = plugins.base; - }; - }; - }); - apps.neovim = flake-utils.lib.mkApp { - drv = packages.neovim; name = "neovim"; exePath = "/bin/nvim"; + in { + packages = rec { + default = nvim; + nvim = pkgs.nvim-pkg; }; - apps.default = apps.neovim; - packages.default = packages.neovim; - }); + devShells = { + default = shell; + }; + }) + // { + overlays.default = neovim-overlay; + }; } diff --git a/nix/mkNeovim.nix b/nix/mkNeovim.nix new file mode 100644 index 0000000..898b312 --- /dev/null +++ b/nix/mkNeovim.nix @@ -0,0 +1,202 @@ +# Function for creating a Neovim derivation +{ + pkgs, + lib, + stdenv, + # Set by the overlay to ensure we use a compatible version of `wrapNeovimUnstable` + pkgs-wrapNeovim ? pkgs, +}: +with lib; + { + # NVIM_APPNAME - Defaults to 'nvim' if not set. + # If set to something else, this will also rename the binary. + appName ? null, + # The Neovim package to wrap + neovim-unwrapped ? pkgs-wrapNeovim.neovim-unwrapped, + 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 + # Additional lua packages (not plugins), e.g. from luarocks.org. + # e.g. p: [p.jsregexp] + extraLuaPackages ? p: [], + extraPython3Packages ? p: [], # Additional python 3 packages + withPython3 ? false, # 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-wrapNeovim.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 prepends 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 + ) + # Prepend nvim and after directories to the runtimepath + # NOTE: This is done after init.lua, + # because of a bug in Neovim that can cause filetype plugins + # to be sourced prematurely, see https://github.com/neovim/neovim/issues/19008 + # We prepend to ensure that user ftplugins are sourced before builtin ftplugins. + + '' + vim.opt.rtp:prepend('${nvimRtp}/nvim') + vim.opt.rtp:prepend('${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"'') + ); + + luaPackages = neovim-unwrapped.lua.pkgs; + resolvedExtraLuaPackages = extraLuaPackages luaPackages; + + # Native Lua libraries + extraMakeWrapperLuaCArgs = + optionalString (resolvedExtraLuaPackages != []) + ''--suffix LUA_CPATH ";" "${concatMapStringsSep ";" luaPackages.getLuaCPath resolvedExtraLuaPackages}"''; + + # Lua libraries + extraMakeWrapperLuaArgs = + optionalString (resolvedExtraLuaPackages != []) + ''--suffix LUA_PATH ";" "${concatMapStringsSep ";" luaPackages.getLuaPath resolvedExtraLuaPackages}"''; + + # wrapNeovimUnstable is the nixpkgs utility function for building a Neovim derivation. + neovim-wrapped = pkgs-wrapNeovim.wrapNeovimUnstable neovim-unwrapped (neovimConfig + // { + luaRcContent = initLua; + wrapperArgs = + escapeShellArgs neovimConfig.wrapperArgs + + " " + + extraMakeWrapperArgs + + " " + + extraMakeWrapperLuaCArgs + + " " + + extraMakeWrapperLuaArgs; + wrapRc = true; + }); + + isCustomAppName = appName != null && appName != "nvim"; + in + neovim-wrapped.overrideAttrs (oa: { + buildPhase = + oa.buildPhase + # If a custom NVIM_APPNAME has been set, rename the `nvim` binary + + lib.optionalString isCustomAppName '' + mv $out/bin/nvim $out/bin/${lib.escapeShellArg appName} + ''; + }) diff --git a/nix/neovim-overlay.nix b/nix/neovim-overlay.nix new file mode 100644 index 0000000..be4e21a --- /dev/null +++ b/nix/neovim-overlay.nix @@ -0,0 +1,105 @@ +# 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; + # }; + + pkgs-wrapNeovim = inputs.nixpkgs.legacyPackages.${pkgs.system}; + + mkNeovim = pkgs.callPackage ./mkNeovim.nix { inherit pkgs-wrapNeovim; }; + + all-plugins = with pkgs.vimPlugins; [ + aerial-nvim + cmp-buffer + cmp-cmdline + cmp-nvim-lsp + cmp-path + cmp-treesitter + cmp_luasnip + diffview-nvim + friendly-snippets + gitsigns-nvim + lualine-nvim + luasnip + mini-nvim + neogen + neogit + nightfox-nvim + nvim-cmp + nvim-lspconfig + nvim-treesitter-context + nvim-treesitter-textobjects + (nvim-treesitter.withPlugins(p: with p; [ + tree-sitter-bash + tree-sitter-c + tree-sitter-comment + tree-sitter-css + tree-sitter-dockerfile + tree-sitter-embedded-template + tree-sitter-go + tree-sitter-gomod + tree-sitter-hcl + tree-sitter-html + tree-sitter-javascript + tree-sitter-json + tree-sitter-lua + tree-sitter-make + tree-sitter-markdown + tree-sitter-markdown-inline + tree-sitter-nix + tree-sitter-php + tree-sitter-python + tree-sitter-regex + tree-sitter-ruby + tree-sitter-sql + tree-sitter-toml + tree-sitter-typescript + tree-sitter-yaml + ])) + nvim-web-devicons + oil-nvim + rose-pine + telescope-fzf-native-nvim + telescope-nvim + toggleterm-nvim + undotree + which-key-nvim + ]; + + extraPackages = with pkgs; [ + ripgrep + gopls + pyright + nil + ]; +in { + nvim-pkg = mkNeovim { + plugins = all-plugins; + inherit extraPackages; + }; + + 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/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/after/plugin/color.lua b/nvim/after/plugin/color.lua new file mode 100644 index 0000000..565df80 --- /dev/null +++ b/nvim/after/plugin/color.lua @@ -0,0 +1,2 @@ +vim.cmd("colorscheme terafox") +vim.keymap.set("n", "aa", "AerialToggle!", { desc = "Toggle Aerial" }) diff --git a/nvim/ftplugin/.gitkeep b/nvim/ftplugin/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/lua/nvim-conf.lua b/nvim/init.lua similarity index 50% rename from config/lua/nvim-conf.lua rename to nvim/init.lua index c7f7014..b0074f2 100644 --- a/config/lua/nvim-conf.lua +++ b/nvim/init.lua @@ -6,8 +6,6 @@ vim.opt.expandtab = true -- insert tabs as spaces vim.opt.inccommand = "split" -- incremental live completion vim.opt.laststatus = 1 vim.opt.list = true --- vim.opt.listchars:append("trail:·") --- vim.opt.listchars:append("leadmultispace:╎ ") vim.opt.nrformats:append("alpha") -- let Ctrl-a do letters as well vim.opt.path:append("**") -- enable fuzzy :find ing vim.opt.relativenumber = true @@ -22,27 +20,14 @@ vim.opt.updatetime = 250 -- decrease update time vim.opt.virtualedit = "onemore" vim.g.fzf_layout = { window = { width = 0.9, height = 0.6 } } -vim.g.indent_blankline_use_treesitter = true -- no highlight floats vim.cmd([[ hi NormalFloat ctermbg=none ]]) --- mappings ----------------------------------------- - -vim.keymap.set("n","gr", "gT", {noremap = true, silent = true}) -vim.keymap.set("n","n", "nzz", {noremap = true, silent = true}) -vim.keymap.set("n", "N", "Nzz", {noremap = true, silent = true}) -vim.keymap.set("n","", "m0i`0", {noremap = true, silent = true}) -vim.keymap.set({'v', 'i'}, 'wq', 'l', {noremap = true, silent = true}) -vim.keymap.set({'n', 'v', 'i'}, 'qwq', 'lwqa', {noremap = true, silent = true}) -vim.keymap.set({'n', 'v'}, 'yy', '"+y', {noremap = true, silent = true}) -vim.keymap.set({'n', 'v'}, 'yp', '"+p', {noremap = true, silent = true}) -vim.keymap.set({'n', 'v'}, 'yd', '"+d', {noremap = true, silent = true}) -- Switch tab length on the fly vim.keymap.set("n", "\\t", function() vim.o.tabstop = vim.o.tabstop == 2 and 4 or 2 -end, { silent = true }) +end, { silent = true, desc = "toggle tabstop"}) -- autocmd ---------------------------------------- @@ -51,3 +36,49 @@ vim.api.nvim_create_autocmd("VimEnter", { command = "silent !mkdir -p " .. undopath, group = vim.api.nvim_create_augroup("Init", {}), }) + +-- Configure Neovim diagnostic messages +local function prefix_diagnostic(prefix, diagnostic) + return string.format(prefix .. ' %s', diagnostic.message) +end +vim.diagnostic.config { + virtual_text = { + prefix = '', + format = function(diagnostic) + local severity = diagnostic.severity + if severity == vim.diagnostic.severity.ERROR then + return prefix_diagnostic('󰅚', diagnostic) + end + if severity == vim.diagnostic.severity.WARN then + return prefix_diagnostic('⚠', diagnostic) + end + if severity == vim.diagnostic.severity.INFO then + return prefix_diagnostic('ⓘ', diagnostic) + end + if severity == vim.diagnostic.severity.HINT then + return prefix_diagnostic('󰌶', diagnostic) + end + return prefix_diagnostic('■', diagnostic) + end, + }, + update_in_insert = false, + underline = true, + severity_sort = true, + float = { + focusable = false, + style = 'minimal', + border = 'rounded', + source = 'if_many', + header = '', + prefix = '', + }, +} + +vim.keymap.set('n', 'ee', function() + local _, winid = vim.diagnostic.open_float(nil, { scope = 'line' }) + if not winid then + vim.notify('no diagnostics found', vim.log.levels.INFO) + return + end + vim.api.nvim_win_set_config(winid or 0, { focusable = true }) +end, { noremap = true, silent = true, desc = 'diagnostics floating window' }) diff --git a/nvim/lua/.gitkeep b/nvim/lua/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/nvim/plugin/aerial.lua b/nvim/plugin/aerial.lua new file mode 100644 index 0000000..30e63aa --- /dev/null +++ b/nvim/plugin/aerial.lua @@ -0,0 +1,13 @@ +if vim.g.did_load_aerial_plugin then + return +end +vim.g.did_load_aerial_plugin = true + +require("aerial").setup({ + default_direction = "left", + autojump = true, + on_attach = function(bufnr) + vim.keymap.set("n", "{", "AerialPrev", { buffer = bufnr }) + vim.keymap.set("n", "}", "AerialNext", { buffer = bufnr }) + end, +}) diff --git a/nvim/plugin/colors.lua b/nvim/plugin/colors.lua new file mode 100644 index 0000000..7ce4a3a --- /dev/null +++ b/nvim/plugin/colors.lua @@ -0,0 +1,19 @@ +if vim.g.did_load_colors_plugin then + return +end +vim.g.did_load_colors_plugin = true + +require("rose-pine").setup({ + variant = "moon", + styles = { + bold = false, + italic = false, + transparency = true, + }, +}) +require('nightfox').setup({ + options = { + transparent = true, -- Disable setting background + terminal_colors = false, -- Set terminal colors (vim.g.terminal_color_*) used in `:terminal` + }, +}) diff --git a/nvim/plugin/completion.lua b/nvim/plugin/completion.lua new file mode 100644 index 0000000..0e30873 --- /dev/null +++ b/nvim/plugin/completion.lua @@ -0,0 +1,47 @@ +if vim.g.did_load_completion_plugin then + return +end +vim.g.did_load_completion_plugin = true +local cmp = require'cmp' + +cmp.setup({ + snippet = { + expand = function(args) + require('luasnip').lsp_expand(args.body) + end, + }, + experimental = { + native_menu = false, + ghost_text = true, + }, + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + ['q'] = cmp.mapping.abort(), + [''] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + }), + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + }, { + { name = 'buffer' }, + }) +}) + +cmp.setup.cmdline({ '/', '?' }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = 'buffer' } + } +}) + +cmp.setup.cmdline(':', { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = 'path' } + }, { + { name = 'cmdline' } + }), + matching = { disallow_symbol_nonprefix_matching = false } +}) diff --git a/nvim/plugin/diffview.lua b/nvim/plugin/diffview.lua new file mode 100644 index 0000000..f63b149 --- /dev/null +++ b/nvim/plugin/diffview.lua @@ -0,0 +1,7 @@ +if vim.g.did_load_diffview_plugin then + return +end +vim.g.did_load_diffview_plugin = true + +require("diffview").setup({ use_icons = false, }) +vim.keymap.set('n', 'gdd', vim.cmd.DiffviewOpen, { desc = '[g]it [d]iffview open' }) diff --git a/nvim/plugin/git.lua b/nvim/plugin/git.lua new file mode 100644 index 0000000..60125f1 --- /dev/null +++ b/nvim/plugin/git.lua @@ -0,0 +1,7 @@ +if vim.g.did_load_diffview_plugin then + return +end +vim.g.did_load_diffview_plugin = true +require("diffview").setup({ + use_icons = false, +}) diff --git a/nvim/plugin/gitsigns.lua b/nvim/plugin/gitsigns.lua new file mode 100644 index 0000000..96b55e3 --- /dev/null +++ b/nvim/plugin/gitsigns.lua @@ -0,0 +1,30 @@ +if vim.g.did_load_gitsigns_plugin then + return +end +vim.g.did_load_gitsigns_plugin = true + +vim.schedule(function() + require('gitsigns').setup{ + signcolumn = false, + numhl = true, + on_attach = function() + local gs = package.loaded.gitsigns + vim.keymap.set("n", "gg", gs.preview_hunk, {desc = "git preview hunk"}) + vim.keymap.set('n', 'gb', function() gs.blame_line{full=true} end, {desc = "git blame_line"}) + vim.keymap.set('n', 'gr', gs.reset_hunk, {desc = "git reset hunk"}) + vim.keymap.set('v', 'gr', function() gs.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end, {desc = "git reset hunk"}) + -- Navigation + vim.keymap.set('n', ']g', function() + if vim.wo.diff then return ']c' end + vim.schedule(function() gs.next_hunk() end) + return '' + end, {expr=true}) + + vim.keymap.set('n', '[g', function() + if vim.wo.diff then return '[c' end + vim.schedule(function() gs.prev_hunk() end) + return '' + end, {expr=true}) + end + } +end) diff --git a/nvim/plugin/keymaps.lua b/nvim/plugin/keymaps.lua new file mode 100644 index 0000000..4b19444 --- /dev/null +++ b/nvim/plugin/keymaps.lua @@ -0,0 +1,13 @@ +vim.keymap.set("n","gr", "gT", {noremap = true, silent = true}) +vim.keymap.set("n","n", "nzz", {noremap = true, silent = true}) +vim.keymap.set("n", "N", "Nzz", {noremap = true, silent = true}) +vim.keymap.set('n', '', 'zz') +vim.keymap.set('n', '', 'zz') +vim.keymap.set('n', '', 'zz') +vim.keymap.set('n', '', 'zz') +vim.keymap.set("n","", "m0i`0", {noremap = true, silent = true}) +vim.keymap.set({'v', 'i'}, 'wq', 'l', {noremap = true, silent = true}) +vim.keymap.set({'n', 'v', 'i'}, 'qwq', 'lwqa', {noremap = true, silent = true}) +vim.keymap.set({'n', 'v'}, 'yy', '"+y', {noremap = true, silent = true, desc = "Yank to clip"}) +vim.keymap.set({'n', 'v'}, 'yp', '"+p', {noremap = true, silent = true, desc = "Paste from clip"}) +vim.keymap.set({'n', 'v'}, 'yd', '"+d', {noremap = true, silent = true, desc = "Delete to clip"}) diff --git a/nvim/plugin/lsp.lua b/nvim/plugin/lsp.lua new file mode 100644 index 0000000..b124502 --- /dev/null +++ b/nvim/plugin/lsp.lua @@ -0,0 +1,65 @@ +if vim.g.did_load_lsp_plugin then + return +end +vim.g.did_load_lsp_plugin = true + +-- Setup language servers. +local lspconfig = require('lspconfig') +local capabilities = require('cmp_nvim_lsp').default_capabilities() + +lspconfig.gopls.setup { on_attach = function(_, bufnr) + capabilities = capabilities + vim.api.nvim_command("au BufWritePre lua vim.lsp.buf.format { async = false }") +end +} +lspconfig.pyright.setup { capabilities = capabilities } +lspconfig.nil_ls.setup { capabilities = capabilities } + +vim.keymap.set('n', 'de', vim.diagnostic.open_float, {desc = "Toggle diagnostic"}) +vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, {desc = "Prev diagnostic"}) +vim.keymap.set('n', ']d', vim.diagnostic.goto_next, {desc = "Next diagnostic"}) + +vim.diagnostic.config({ + virtual_text = true, + underline = true, + update_in_insert = false, +}) +-- Use LspAttach autocommand to only map the following keys +-- after the language server attaches to the current buffer +vim.api.nvim_create_autocmd('LspAttach', { + group = vim.api.nvim_create_augroup('UserLspConfig', {}), + callback = function(ev) + local bufnr = ev.buf + local client = vim.lsp.get_client_by_id(ev.data.client_id) + -- Buffer local mappings. + -- See `:help vim.lsp.*` for documentation on any of the below functions + vim.keymap.set('n', 'K', vim.lsp.buf.hover, { buffer = ev.buf, noremap = true, silent = true , desc = "LSP hover"}) + vim.keymap.set('n', 'rn', vim.lsp.buf.rename, { buffer = ev.buf, noremap = true, silent = true , desc = "LSP Rename"}) + vim.keymap.set({ 'n', 'v' }, 'da', vim.lsp.buf.code_action, { buffer = ev.buf, noremap = true, silent = true , desc = "LSP code action"}) + vim.keymap.set("n", "dd", "Telescope lsp_definitions", { buffer = ev.buf, noremap = true, silent = true , desc = "LSP definitions"}) + vim.keymap.set("n", "di", "Telescope lsp_implementations", { buffer = ev.buf, noremap = true, silent = true , desc = "LSP implementations"}) + vim.keymap.set("n", "dr", "Telescope lsp_references", { buffer = ev.buf, noremap = true, silent = true , desc = "LSP references"}) + vim.keymap.set("n", "dt", "Telescope lsp_type_definitions", { buffer = ev.buf, noremap = true, silent = true , desc = "LSP type defs"}) + vim.keymap.set("n", "ds", "Telescope lsp_document_symbols", { buffer = ev.buf, noremap = true, silent = true , desc = "LSP symbols"}) + vim.keymap.set('n', 'dl', vim.lsp.codelens.run, { buffer = ev.buf, noremap = true, silent = true , desc = "LSP codelens"}) + vim.keymap.set('n', 'df', function() + vim.lsp.buf.format { async = true } + end,{ buffer = ev.buf, noremap = true, silent = true , desc = "LSP format"}) + -- Auto-refresh code lenses + if not client then + return + end + local group = vim.api.nvim_create_augroup(string.format('lsp-%s-%s', bufnr, client.id), {}) + if client.server_capabilities.codeLensProvider then + vim.api.nvim_create_autocmd({ 'InsertLeave', 'BufWritePost', 'TextChanged' }, { + group = group, + callback = function() + vim.lsp.codelens.refresh { bufnr = bufnr } + end, + buffer = bufnr, + }) + vim.lsp.codelens.refresh { bufnr = bufnr } + end + end, +}) + diff --git a/nvim/plugin/lualine.lua b/nvim/plugin/lualine.lua new file mode 100644 index 0000000..7aff49c --- /dev/null +++ b/nvim/plugin/lualine.lua @@ -0,0 +1,11 @@ +if vim.g.did_load_lualine_plugin then + return +end +vim.g.did_load_lualine_plugin = true + +vim.schedule(function() + require('lualine').setup { + globalstatus = true, + extensions = { 'fugitive', 'fzf', 'toggleterm', 'quickfix' }, + } +end) diff --git a/nvim/plugin/luasnip.lua b/nvim/plugin/luasnip.lua new file mode 100644 index 0000000..b6840d6 --- /dev/null +++ b/nvim/plugin/luasnip.lua @@ -0,0 +1,37 @@ +if vim.g.did_load_luasnip_plugin then + return +end +vim.g.did_load_luasnip_plugin = true + +local ls = require("luasnip") +ls.config.set_config { + history = true, + updateevents = "TextChanged, TextChangedI", +} +require("luasnip.loaders.from_vscode").lazy_load() + +vim.keymap.set({"i", "s"}, "", function() + if ls.expand_or_jumpable() then + ls.expand_or_jump() + end +end, {silent = true}) + +vim.keymap.set({"i", "s"}, "", function() + if ls.jumpable(-1) then + ls.jump(-1) + end +end, {silent = true}) + +vim.keymap.set({"i", "s"}, "", function() + if ls.choice_active() then + ls.change_choice(1) + end +end, {silent = true}) + +-------------------- +-- Snippets -- +-------------------- +local fmta = require("luasnip.extras.fmt").fmta +ls.add_snippets("go", { + ls.snippet("ie", fmta("if err != nil {\n\treturn \n}", { err = ls.insert_node(1, "err") })), +}) diff --git a/config/lua/mini-conf.lua b/nvim/plugin/mini.lua similarity index 67% rename from config/lua/mini-conf.lua rename to nvim/plugin/mini.lua index 184101f..166b99e 100644 --- a/config/lua/mini-conf.lua +++ b/nvim/plugin/mini.lua @@ -1,3 +1,8 @@ +if vim.g.did_load_mini_plugin then + return +end +vim.g.did_load_mini_plugin = true + -- din( dina require('mini.ai').setup() -- gc gcc @@ -47,19 +52,7 @@ require('mini.splitjoin').setup({ } }) -require('mini.pairs').setup( -{ - modes = {insert = true, command = false, terminal = false}, - mappings = { - ['['] = { action = 'open', pair = '[]', neigh_pattern = '[^\\].' }, - ['{'] = { action = 'open', pair = '{}', neigh_pattern = '[^\\].' }, - [']'] = { action = 'close', pair = '[]', neigh_pattern = '[^\\].' }, - ['}'] = { action = 'close', pair = '{}', neigh_pattern = '[^\\].' }, - ['"'] = { }, - ['\''] = { }, - }, -} -) +require('mini.pairs').setup() vim.cmd([[ hi MiniCursorwordCurrent ctermfg=240 ]]) -- f F t T @@ -74,17 +67,3 @@ indent.setup({ draw = { delay = 0 } }) indent.gen_animation.none() - --- --- require('mini.completion').setup({ --- delay = {completion = 10^7}, --- window = { --- info = { height = 25, width = 80, border = 'single' }, --- signature = { height = 25, width = 80, border = 'single' }, --- }, --- lsp_completion = { --- source_func = 'completefunc', --- auto_setup = true, --- }, --- fallback_action = "" --- }) diff --git a/nvim/plugin/misc.lua b/nvim/plugin/misc.lua new file mode 100644 index 0000000..9c4d310 --- /dev/null +++ b/nvim/plugin/misc.lua @@ -0,0 +1,20 @@ +if vim.g.did_load_plugins_plugin then + return +end +vim.g.did_load_plugins_plugin = true + +-- many plugins annoyingly require a call to a 'setup' function to be loaded, +-- even with default configs + +require("neogen").setup{} +vim.keymap.set("n","nd", "Neogen", {noremap = true, silent = true, desc = "Neogen - gen comments"}) + +require("toggleterm").setup{ + open_mapping = [[]], + direction = "float", + close_on_exit = true, +} + +require('which-key').setup { + preset = 'helix' +} diff --git a/nvim/plugin/neogit.lua b/nvim/plugin/neogit.lua new file mode 100644 index 0000000..3ef2047 --- /dev/null +++ b/nvim/plugin/neogit.lua @@ -0,0 +1,15 @@ +if vim.g.did_load_neogit_plugin then + return +end +vim.g.did_load_neogit_plugin = true + +local neogit = require('neogit') +neogit.setup { + disable_builtin_notifications = true, + integrations = { + diffview = true, + telescope = true, + fzf_lua = true, + }, +} +vim.keymap.set('n', 'ng', neogit.open, { noremap = true, silent = true, desc = "Neogit"}) diff --git a/nvim/plugin/oil.lua b/nvim/plugin/oil.lua new file mode 100644 index 0000000..1b38b6a --- /dev/null +++ b/nvim/plugin/oil.lua @@ -0,0 +1,23 @@ +if vim.g.did_load_oil_plugin then + return +end +vim.g.did_load_oil_plugin = true + +local oil = require('oil') +oil.setup({ + watch_for_changes = true, + columns = { + "permissions", + "size" + }, + view_options = { + show_hidden = true + }, + keymaps = { + ["wq"] = "actions.close" + } +}) +vim.keymap.set("n", "c", oil.toggle_float, {noremap = true, silent = true}); +vim.keymap.set("n", "u", "UndotreeToggle") +vim.g.undotree_ShortIndicators = 1 +vim.g.undotree_SetFocusWhenToggle = 1 diff --git a/nvim/plugin/statuscol.lua b/nvim/plugin/statuscol.lua new file mode 100644 index 0000000..60125f1 --- /dev/null +++ b/nvim/plugin/statuscol.lua @@ -0,0 +1,7 @@ +if vim.g.did_load_diffview_plugin then + return +end +vim.g.did_load_diffview_plugin = true +require("diffview").setup({ + use_icons = false, +}) diff --git a/nvim/plugin/telescope.lua b/nvim/plugin/telescope.lua new file mode 100644 index 0000000..ce35f8d --- /dev/null +++ b/nvim/plugin/telescope.lua @@ -0,0 +1,62 @@ +if vim.g.did_load_telescope_plugin then + return +end +vim.g.did_load_telescope_plugin = true + +local telescope = require("telescope.builtin") + +-- Fall back to find_files if not in a git repo +local project_files = function() + local opts = {} -- define here if you want to define something + local ok = pcall(telescope.git_files, opts) + if not ok then + telescope.find_files(opts) + end +end + +vim.keymap.set("n", "", telescope.buffers, {noremap = true, silent = true, desc = "Fuzzy find buffers"}) +vim.keymap.set("n", "ff", project_files, {noremap = true, silent = true, desc = "Fuzzy find git files"}) +vim.keymap.set("n", "fg", telescope.find_files, {noremap = true, silent = true, desc = "Fuzzy find files"}) +vim.keymap.set("n", "fc", telescope.command_history, {noremap = true, silent = true, desc = "Fuzzy find command_history"}) +vim.keymap.set("n", "fa", telescope.live_grep, {noremap = true, silent = true, desc = "Fuzzy find grep"}) +vim.keymap.set("n", "f8", telescope.grep_string, {noremap = true, silent = true, desc = "Fuzzy find grep current word"}) +vim.keymap.set("n", "fs", telescope.treesitter, {noremap = true, silent = true, desc = "Fuzzy find treesitter objects"}) +vim.keymap.set("n", "fq", telescope.quickfix, {noremap = true, silent = true, desc = "Fuzzy find quickfix"}) +vim.keymap.set("n", "f", telescope.resume, {noremap = true, silent = true, desc = "Fuzzy find resume"}) + +local telescope = require("telescope") +telescope.setup({ + defaults = { + layout_strategy = "vertical", + layout_config = { width = .90, }, + prompt_title = false, + results_title = false, + preview_title = false, + vimgrep_arguments = { + "rg", + '-L', + "--color=never", + "--no-heading", + "--hidden", + "--with-filename", + "--line-number", + "--column", + "--smart-case" + }, + preview = { + treesitter = true, + }, + path_display = { + 'truncate', + }, + mappings = { + i = { + ["wq"] = require("telescope.actions").close, + [""] = require("telescope.actions").close, + [""] = require("telescope.actions").move_selection_previous, + [""] = require("telescope.actions").move_selection_next, + }, + }, + }, +}) +telescope.load_extension("fzf") diff --git a/nvim/plugin/treesitter.lua b/nvim/plugin/treesitter.lua new file mode 100644 index 0000000..ed6e111 --- /dev/null +++ b/nvim/plugin/treesitter.lua @@ -0,0 +1,65 @@ +if vim.g.did_load_treesitter_plugin then + return +end +vim.g.did_load_treesitter_plugin = true + +require("nvim-treesitter.configs").setup { + ensure_installed = {}, + highlight = { + enable = true, + disable = function(_, buf) + local max_filesize = 100 * 1024 -- 100 KiB + local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) + if ok and stats and stats.size > max_filesize then + return true + end + end, + }, + indent = { + enable = true, + }, + textobjects = { + select = { + enable = true, + lookahead = true, + keymaps = { + ["af"] = "@function.outer", + ["if"] = "@function.inner", + ["aa"] = "@statement.outer", + ["ia"] = "@parameter.inner", + }, + }, + move = { + enable = true, + set_jumps = true, -- whether to set jumps in the jumplist + goto_next_start = { + [']]'] = '@function.outer', + [']a'] = '@parameter.inner', + }, + goto_previous_start = { + ['[['] = '@function.outer', + ['[a'] = '@parameter.inner', + }, + }, + swap = { + enable = true, + swap_next = { + ["s]"] = "@parameter.inner", + }, + swap_previous = { + ["s["] = "@parameter.inner", + }, + }, }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = '', + node_incremental = '', + node_decremental = '', + }, + }, +} + +require('treesitter-context').setup { + max_lines = 3, +} diff --git a/nvim/plugin/which-key.lua b/nvim/plugin/which-key.lua new file mode 100644 index 0000000..def52f8 --- /dev/null +++ b/nvim/plugin/which-key.lua @@ -0,0 +1,3 @@ +require('which-key').setup { + preset = 'helix' +} diff --git a/plugins.nix b/plugins.nix deleted file mode 100644 index 481752c..0000000 --- a/plugins.nix +++ /dev/null @@ -1,57 +0,0 @@ -{pkgs, ...}: -{ - base = with pkgs.vimPlugins; [ - aerial-nvim - cmp-buffer - cmp-cmdline - cmp-nvim-lsp - cmp-path - cmp-treesitter - cmp_luasnip - diffview-nvim - friendly-snippets - gitsigns-nvim - luasnip - mini-nvim - neogen - neogit - nvim-cmp - nvim-lspconfig - nvim-treesitter-textobjects - (nvim-treesitter.withPlugins(p: with p; [ - tree-sitter-bash - tree-sitter-c - tree-sitter-comment - tree-sitter-css - tree-sitter-dockerfile - tree-sitter-embedded-template - tree-sitter-go - tree-sitter-gomod - tree-sitter-hcl - tree-sitter-html - tree-sitter-javascript - tree-sitter-json - tree-sitter-lua - tree-sitter-make - tree-sitter-markdown - tree-sitter-markdown-inline - tree-sitter-nix - tree-sitter-php - tree-sitter-python - tree-sitter-regex - tree-sitter-ruby - tree-sitter-sql - tree-sitter-toml - tree-sitter-typescript - tree-sitter-yaml - ])) - oil-nvim - refactoring-nvim - rose-pine - telescope-fzf-native-nvim - telescope-nvim - toggleterm-nvim - undotree - vim-nix - ]; -}