├── .gitignore ├── .stylua.toml ├── LICENSE ├── README.md ├── docs └── images │ └── screenshot.png ├── init.lua ├── lsp └── lua_ls.lua ├── lua ├── core │ ├── autocmd.lua │ ├── functions.lua │ ├── keys.lua │ └── options.lua ├── lib │ ├── icons.lua │ ├── prompts.lua │ └── util.lua └── plugins │ ├── ai │ ├── avante.lua │ ├── copilot.lua │ └── mcphub.lua │ ├── editor │ ├── ai.lua │ ├── bracketed.lua │ ├── pairs.lua │ ├── spider.lua │ ├── surround.lua │ ├── textobjects.lua │ └── treesitter.lua │ ├── lang │ ├── blink.lua │ ├── lspconfig.lua │ ├── lspsaga.lua │ ├── mason.lua │ └── null-ls.lua │ ├── lazy.lua │ ├── list.lua │ ├── lock.json │ ├── tools │ ├── ccc.lua │ ├── dap.lua │ ├── dbee.lua │ ├── exercism.lua │ ├── files.lua │ ├── flash.lua │ ├── gitlinker.lua │ ├── navigator.lua │ ├── neotest.lua │ ├── octohub.lua │ ├── sniprun.lua │ └── spectre.lua │ └── ui │ ├── gitsigns.lua │ ├── lualine.lua │ ├── markit.lua │ ├── onedark.lua │ ├── snacks.lua │ └── which-key.lua └── plugin └── after └── highlights.lua /.gitignore: -------------------------------------------------------------------------------- 1 | # Packer compiled output 2 | plugin/packer_compiled.lua 3 | 4 | # Custom user configs 5 | lua/user/ 6 | -------------------------------------------------------------------------------- /.stylua.toml: -------------------------------------------------------------------------------- 1 | call_parentheses = "Always" 2 | collapse_simple_statement = "Never" 3 | column_width = 120 4 | indent_type = "Spaces" 5 | indent_width = 4 6 | line_endings = "Unix" 7 | quote_style = "AutoPreferSingle" 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

nvim2k

4 | 5 | 6 | License 7 | 8 | 9 | People 10 | 11 | 12 | Stars 13 | 14 | 15 | Forks 16 | 17 | 18 | Watches 19 | 20 | 21 | Last Updated 22 | 23 |

Your Personalized Dev Env ❤️👨‍💻

24 | 25 |
26 | nvim2k Demo 27 |
28 |
nvim2k screenshot
29 |
30 | 31 |
32 | 33 | Handcrafted Neovim setup for the ultimate CLI dev experience. 34 | 35 | Here's a [YouTube playlist](https://www.youtube.com/watch?v=Pj7jJnOcW9I&list=PL52YFor3VtLdye3d4NiLHA7h4v5_kj5_C) that contains all the videos I made related to nvim2k. 36 | 37 | ## ✨ Features 38 | 39 | - **Fully configured LSP**: Out of the box LSP and completions, including Copilot (optional) 40 | - **Awesome keybindings**: Intuitive and well documented keybindings with which-key 41 | - **Blazingly fast**: Starts up in less than 30ms thanks to extensive lazy loading 42 | - **Batteries included**: Has all the necessary plugins included out of the box 43 | - **Git in there**: Powerful git integrations thanks to lazygit, fugitive, gitsigns and more 44 | - **Pretty colors**: Comes with treesitter and onedark preconfigured with full transparency support 45 | - **Goto for notes**: Comes with powerful note-taking capabilities, thanks to [tdo](https://github.com/2kabhishek/tdo) 46 | - **Tmux integration**: Works with your tmux configurations out of the box 47 | - **Dev tools**: Comes with debugging, testing, database and REPL support, pick and choose 48 | - **Auto install**: All necessary LSPs, Null LS sources, Treesitter Parsers etc. are auto installed 49 | - **User module**: Configure nvim2k according to your needs by using the `user` module! 50 | - and some more 51 | 52 | Most importantly: 53 | 54 | **Built for extending**: nvim2k has a easy to understand config structure that promotes personalization, so go ahead, bring your keybindings, functions and plugins over, and truly make **nvim2k: Your Personalized Development Environment!** 55 | 56 | ## ⚡ Setup 57 | 58 | ### ⚙️ Requirements 59 | 60 | Before you begin, ensure you have met the following requirements: 61 | 62 | - You have installed the latest version of `neovim` 63 | - Some command line tools: fd, ripgrep 64 | - To use nvim2k for notes, take a look at [tdo.nvim](https://github.com/2kabhishek/tdo.nvim) 65 | 66 | ### 💻 Installation 67 | 68 | To install `nvim2k` clone the repo and setup the symlink 69 | 70 | ```bash 71 | git clone https://github.com/2kabhishek/nvim2k 72 | ``` 73 | 74 | On Linux and Mac 75 | 76 | ```bash 77 | ln -sfnv $PWD/nvim2k $HOME/.config/nvim 78 | ``` 79 | 80 | On Windows Powershell 81 | 82 | ```powershell 83 | New-Item -ItemType SymbolicLink -Path "$env:LOCALAPPDATA\nvim" -Target "$PWD\nvim2k" -Force 84 | ``` 85 | 86 | ## 🚀 Usage 87 | 88 | ### 🎨 User Configs 89 | 90 | `nvim2k` supports a user module where you can store your custom configs and override any default configs. 91 | 92 | To use custom configs create the file `lua/user/init.lua` in nvim2k, with the following structure: 93 | 94 | ```lua 95 | -- lua/user/init.lua 96 | local user = { 97 | auto_install = true, -- enable auto install of LSPs, Treesitter parsers etc. 98 | user_lsp_servers = { 99 | -- Auto installed LSPs defined by user 100 | }, 101 | user_null_ls_sources = { 102 | -- Auto installed Null LS sources defined by user 103 | }, 104 | user_treesitter_parsers = { 105 | -- Auto installed Treesitter parsers defined by user 106 | }, 107 | 108 | enable_db_explorer = false, -- enable dbee.nvim support 109 | enable_debugger = false, -- enable dap.nvim support 110 | enable_test_runner = false, -- enable neotest.nvim support 111 | enable_trainer = false, -- enable hardtime.nvim support 112 | user_plugins = { 113 | -- Add your lazy plugin spec here 114 | }, 115 | 116 | user_keybindings = { 117 | -- Add your which-key bindings here 118 | } 119 | } 120 | 121 | return user 122 | ``` 123 | 124 | You can add and `require` any other custom modules and configurations you want in this file. 125 | 126 | `user` module is not part of the repo, you can set up `user` module as a separate git repository while continuing to receive `nvim2k` updates. 127 | 128 | ### Core 129 | 130 | Files in [lua/core](./lua/core/) control the core of neovim: 131 | 132 | - [options](./lua/core/options.lua), 133 | - [functions](./lua/core/functions.lua) 134 | - [autocmds](./lua/core/autocmd.lua) 135 | - [core keybindings](./lua/core/keys.lua) 136 | 137 | ### ⌨️ Keybindings 138 | 139 | Apart from [core/keys](./lua/core/keys.lua) most keybindings are configured using [which-key](./lua/plugins/tools/which-key.lua) 140 | 141 | ### 📦 Plugins 142 | 143 | You can check out the [plugins list file](./lua/plugins/list.lua) file to see the plugins that are included in nvim2k. 144 | 145 | - [lang](./lua/plugins/lang/): Plugins related to language features, completions, lsp, editing etc. 146 | - [tools](./lua/plugins/tools/): Plugins that add tool integrations to the editor. 147 | - [ui](./lua/plugins/ui/): Plugins that make improve Neovim user experience. 148 | 149 | ## 🧑‍💻 Behind The Code 150 | 151 | ### 🌈 Inspiration 152 | 153 | I have been using vim/neovim for 7+ years now, I wanted to share my config for everyone to use 154 | 155 | ### 💡 Challenges/Learnings 156 | 157 | - Finding out the right plugins and configs! 158 | - Setting up the initial config structure with lazy loading was tough. 159 | 160 | ### 🧰 Tools Used 161 | 162 | - [dots2k](https://github.com/2kabhishek/dots2k) — Dev Environment 163 | - [nvim2k](https://github.com/2kabhishek/nvim2k) — Personalized Editor 164 | - [sway2k](https://github.com/2kabhishek/sway2k) — Desktop Environment 165 | - [qute2k](https://github.com/2kabhishek/qute2k) — Personalized Browser 166 | 167 | ### 🔍 More Info 168 | 169 | - [tdo.nvim](https://github.com/2kabhishek/tdo.nvim) — note taking system in neovim 170 | - [termim.nvim](https://github.com/2kabhishek/termim.nvim) — enhanced neovim terminal 171 | - [nerdy.nvim](https://github.com/2kabhishek/nerdy.nvim) — search nerdfont glyphs from inside neovim 172 | - [co-author.nvim](https://github.com/2kabhishek/co-author.nvim) — add co authors to your git commits 173 | 174 |
175 | 176 |
177 | 178 | ⭐ hit the star button if you found this useful ⭐
179 | 180 | Source 181 | | Blog 182 | | Twitter 183 | | LinkedIn 184 | | More Links 185 | | Other Projects 186 | 187 |
188 | -------------------------------------------------------------------------------- /docs/images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2KAbhishek/nvim2k/f5c5ef5decd537112702c2ef9dd6b274d57174a7/docs/images/screenshot.png -------------------------------------------------------------------------------- /init.lua: -------------------------------------------------------------------------------- 1 | require('core.options') 2 | require('core.functions') 3 | require('core.keys') 4 | require('core.autocmd') 5 | require('plugins.lazy') 6 | -- Add user configs to this module 7 | pcall(require, 'user') 8 | -------------------------------------------------------------------------------- /lsp/lua_ls.lua: -------------------------------------------------------------------------------- 1 | return { 2 | cmd = { 'lua-language-server' }, 3 | filetypes = { 'lua' }, 4 | root_markers = { '.luarc.json', '.luarc.jsonc' }, 5 | settings = { 6 | Lua = { 7 | diagnostics = { globals = { 'vim' } }, 8 | telemetry = { enable = false }, 9 | format = { 10 | enable = true, 11 | defaultConfig = { 12 | align_continuous_assign_statement = false, 13 | align_continuous_rect_table_field = false, 14 | align_array_table = false, 15 | }, 16 | }, 17 | runtime = { 18 | version = 'LuaJIT', 19 | path = { 20 | 'lua/?.lua', 21 | 'lua/?/init.lua', 22 | }, 23 | }, 24 | workspace = { 25 | checkThirdParty = false, 26 | library = { 27 | vim.env.VIMRUNTIME, 28 | -- vim.api.nvim_get_runtime_file('', true), 29 | -- '${3rd}/busted/library' 30 | }, 31 | }, 32 | }, 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /lua/core/autocmd.lua: -------------------------------------------------------------------------------- 1 | local function augroup(name) 2 | return vim.api.nvim_create_augroup('nvim2k_' .. name, { clear = true }) 3 | end 4 | 5 | -- Strip trailing spaces before write 6 | vim.api.nvim_create_autocmd({ 'BufWritePre' }, { 7 | group = augroup('strip_space'), 8 | pattern = { '*' }, 9 | callback = function() 10 | vim.cmd([[ %s/\s\+$//e ]]) 11 | end, 12 | }) 13 | 14 | -- Check if we need to reload the file when it changed 15 | vim.api.nvim_create_autocmd({ 'FocusGained', 'TermClose', 'TermLeave' }, { 16 | group = augroup('checktime'), 17 | command = 'checktime', 18 | }) 19 | 20 | -- Highlight on yank 21 | vim.api.nvim_create_autocmd('TextYankPost', { 22 | group = augroup('highlight_yank'), 23 | callback = function() 24 | vim.highlight.on_yank() 25 | end, 26 | }) 27 | 28 | -- resize splits if window got resized 29 | vim.api.nvim_create_autocmd({ 'VimResized' }, { 30 | group = augroup('resize_splits'), 31 | callback = function() 32 | vim.cmd('tabdo wincmd =') 33 | end, 34 | }) 35 | 36 | -- go to last loc when opening a buffer 37 | vim.api.nvim_create_autocmd('BufReadPost', { 38 | group = augroup('last_loc'), 39 | callback = function() 40 | local mark = vim.api.nvim_buf_get_mark(0, '"') 41 | local lcount = vim.api.nvim_buf_line_count(0) 42 | if mark[1] > 0 and mark[1] <= lcount then 43 | pcall(vim.api.nvim_win_set_cursor, 0, mark) 44 | end 45 | end, 46 | }) 47 | 48 | -- close some filetypes with 49 | vim.api.nvim_create_autocmd('FileType', { 50 | group = augroup('close_with_q'), 51 | pattern = { 52 | 'Jaq', 53 | 'PlenaryTestPopup', 54 | 'Avante', 55 | 'AvanteInput', 56 | 'AvanteSelectedFiles', 57 | 'fugitive', 58 | 'git', 59 | 'help', 60 | 'lir', 61 | 'lspinfo', 62 | 'man', 63 | 'netrw', 64 | 'notify', 65 | 'qf', 66 | 'spectre_panel', 67 | 'startuptime', 68 | 'tsplayground', 69 | }, 70 | callback = function(event) 71 | vim.bo[event.buf].buflisted = false 72 | vim.keymap.set('n', 'q', 'close', { buffer = event.buf, silent = true }) 73 | end, 74 | }) 75 | 76 | -- wrap and check for spell in text filetypes 77 | vim.api.nvim_create_autocmd('FileType', { 78 | group = augroup('wrap_spell'), 79 | pattern = { 'gitcommit', 'markdown' }, 80 | callback = function() 81 | vim.opt_local.wrap = true 82 | vim.opt_local.spell = true 83 | end, 84 | }) 85 | 86 | -- Auto create dir when saving a file, in case some intermediate directory does not exist 87 | vim.api.nvim_create_autocmd({ 'BufWritePre' }, { 88 | group = augroup('auto_create_dir'), 89 | callback = function(event) 90 | local file = vim.loop.fs_realpath(event.match) or event.match 91 | vim.fn.mkdir(vim.fn.fnamemodify(file, ':p:h'), 'p') 92 | end, 93 | }) 94 | 95 | -- Set arb filetype 96 | vim.api.nvim_create_autocmd({ 'BufEnter' }, { 97 | group = augroup('set_file_type'), 98 | pattern = { '*.arb' }, 99 | command = require('lib.util').get_file_type_cmd('arb'), 100 | }) 101 | 102 | -- Disable format options 103 | vim.api.nvim_create_autocmd('FileType', { 104 | group = augroup('disable_formatoptions'), 105 | pattern = '*', 106 | callback = function() 107 | vim.opt_local.formatoptions:remove({ 'c', 'r', 'o' }) 108 | end, 109 | }) 110 | 111 | local function enable_autoformat() 112 | vim.api.nvim_create_autocmd({ 'BufWritePre' }, { 113 | group = augroup('autoformat'), 114 | pattern = { '*' }, 115 | callback = function() 116 | vim.lsp.buf.format() 117 | end, 118 | }) 119 | end 120 | 121 | enable_autoformat() 122 | 123 | vim.api.nvim_create_user_command('WriteNoFormat', function() 124 | -- Temporarily disable the autoformat autocmd 125 | vim.api.nvim_del_augroup_by_name('nvim2k_autoformat') 126 | vim.cmd('write') 127 | -- Re-enable the autoformat autocmd 128 | enable_autoformat() 129 | end, {}) 130 | -------------------------------------------------------------------------------- /lua/core/functions.lua: -------------------------------------------------------------------------------- 1 | -- Reload neovim config 2 | vim.api.nvim_create_user_command('ReloadConfig', function() 3 | for name, _ in pairs(package.loaded) do 4 | if name:match('^plugins') then 5 | package.loaded[name] = nil 6 | end 7 | end 8 | 9 | dofile(vim.env.MYVIMRC) 10 | vim.notify('Nvim configuration reloaded!', vim.log.levels.INFO) 11 | end, {}) 12 | 13 | local function copy_to_clipboard(content, message) 14 | vim.fn.setreg('+', content) 15 | vim.notify('Copied "' .. content .. '" to the clipboard!', vim.log.levels.INFO) 16 | end 17 | 18 | vim.api.nvim_create_user_command('CopyRelativePath', function() 19 | local path = vim.fn.expand('%') 20 | copy_to_clipboard(path, 'Copied "' .. path .. '" to the clipboard!') 21 | end, {}) 22 | 23 | vim.api.nvim_create_user_command('CopyAbsolutePath', function() 24 | local path = vim.fn.expand('%:p') 25 | copy_to_clipboard(path, 'Copied "' .. path .. '" to the clipboard!') 26 | end, {}) 27 | 28 | vim.api.nvim_create_user_command('CopyRelativePathWithLine', function() 29 | local path = vim.fn.expand('%') 30 | local line = vim.fn.line('.') 31 | local result = path .. ':' .. line 32 | copy_to_clipboard(result, 'Copied "' .. result .. '" to the clipboard!') 33 | end, {}) 34 | 35 | vim.api.nvim_create_user_command('CopyAbsolutePathWithLine', function() 36 | local path = vim.fn.expand('%:p') 37 | local line = vim.fn.line('.') 38 | local result = path .. ':' .. line 39 | copy_to_clipboard(result, 'Copied "' .. result .. '" to the clipboard!') 40 | end, {}) 41 | 42 | vim.api.nvim_create_user_command('CopyFileName', function() 43 | local path = vim.fn.expand('%:t') 44 | copy_to_clipboard(path, 'Copied "' .. path .. '" to the clipboard!') 45 | end, {}) 46 | 47 | -- Switch to git root or file parent dir 48 | vim.api.nvim_create_user_command('RootDir', function() 49 | local root = require('lib.util').get_root_dir() 50 | 51 | if root == '' then 52 | return 53 | end 54 | vim.cmd('lcd ' .. root) 55 | end, {}) 56 | -------------------------------------------------------------------------------- /lua/core/keys.lua: -------------------------------------------------------------------------------- 1 | local function map(mode, lhs, rhs, opts) 2 | opts = opts or {} 3 | opts.silent = opts.silent ~= false 4 | vim.keymap.set(mode, lhs, rhs, opts) 5 | end 6 | local opts = { noremap = true, silent = true } 7 | 8 | -- Space as leader 9 | map('n', '', '', opts) 10 | vim.g.mapleader = ' ' 11 | vim.g.maplocalleader = ' ' 12 | 13 | -- Modes 14 | -- normal_mode = "n", insert_mode = "i", visual_mode = "v", 15 | -- visual_block_mode = "x", term_mode = "t", command_mode = "c", 16 | 17 | -- Use jj as escape 18 | map('i', 'jj', '', opts) 19 | map('t', 'JJ', '', opts) 20 | 21 | -- Visual overwrite paste 22 | map({ 'v', 'x' }, 'p', '"_dP', opts) 23 | 24 | -- Do not copy on x 25 | map({ 'v', 'x' }, 'x', '"_x', opts) 26 | map('n', 'X', '"_D', opts) 27 | map({ 'v', 'x' }, 'X', '"_d', opts) 28 | 29 | -- Increment/decrement 30 | map({ 'n', 'v', 'x' }, '-', '', opts) 31 | map({ 'n', 'v', 'x' }, '=', '', opts) 32 | 33 | -- Move to line beginning and end 34 | map({ 'n', 'v', 'x' }, 'gl', '$', { desc = 'End of line' }) 35 | map({ 'n', 'v', 'x' }, 'gh', '^', { desc = 'Beginning of line' }) 36 | 37 | -- Center Cursors 38 | map('n', 'J', 'mzJ`z', opts) 39 | map('n', '', 'zz', opts) 40 | map('n', '', 'zz', opts) 41 | map('n', 'n', 'nzzzv', opts) 42 | map('n', 'N', 'Nzzzv', opts) 43 | 44 | -- Better up/down 45 | map('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) 46 | map('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) 47 | 48 | -- Move text up and down 49 | map({ 'v', 'x' }, 'J', ":move '>+1gv-gv", opts) 50 | map({ 'v', 'x' }, 'K', ":move '<-2gv-gv", opts) 51 | 52 | -- Clear search, diff update and redraw 53 | map({ 'i', 'n' }, '', 'noh', { desc = 'Escape and clear hlsearch' }) 54 | 55 | -- Consistent n/N search navigation 56 | map('n', 'n', "'Nn'[v:searchforward]", { expr = true, desc = 'Next search result' }) 57 | map('x', 'n', "'Nn'[v:searchforward]", { expr = true, desc = 'Next search result' }) 58 | map('o', 'n', "'Nn'[v:searchforward]", { expr = true, desc = 'Next search result' }) 59 | map('n', 'N', "'nN'[v:searchforward]", { expr = true, desc = 'Prev search result' }) 60 | map('x', 'N', "'nN'[v:searchforward]", { expr = true, desc = 'Prev search result' }) 61 | map('o', 'N', "'nN'[v:searchforward]", { expr = true, desc = 'Prev search result' }) 62 | 63 | -- Better indenting 64 | map('v', '<', '', '>gv') 66 | 67 | -- Add undo breakpoints 68 | map('i', ',', ',u') 69 | map('i', '.', '.u') 70 | map('i', ';', ';u') 71 | -------------------------------------------------------------------------------- /lua/core/options.lua: -------------------------------------------------------------------------------- 1 | local options = { 2 | ai = true, 3 | autoindent = true, 4 | autowrite = true, 5 | backspace = 'indent,eol,start', 6 | backup = false, -- creates a backup file 7 | breakindent = true, 8 | clipboard = 'unnamedplus', -- allows neovim to access the system clipboard 9 | cmdheight = 1, -- more space in the neovim command line for displaying messages 10 | completeopt = 'menu,menuone,noselect', -- mostly just for cmp 11 | conceallevel = 0, -- so that `` is visible in markdown files 12 | confirm = true, -- Confirm to save changes before exiting modified buffer 13 | cursorline = true, -- highlight the current line 14 | expandtab = true, -- convert tabs to spaces 15 | fileencoding = 'utf-8', -- the encoding written to a file 16 | formatoptions = 'jlnqt', -- set formatoptions, check help fo-table 17 | grepformat = '%f:%l:%c:%m', 18 | grepprg = 'rg --vimgrep', 19 | hlsearch = true, -- highlight all matches on previous search pattern 20 | ignorecase = true, -- ignore case in search patterns 21 | inccommand = 'split', -- preview incremental substitute 22 | laststatus = 3, 23 | list = true, 24 | listchars = { trail = '', tab = '', nbsp = '_', extends = '>', precedes = '<' }, -- highlight 25 | mouse = 'a', -- allow the mouse to be used in neovim 26 | number = true, -- set numbered lines 27 | numberwidth = 4, -- set number column width to 2 {default 4} 28 | pumblend = 10, -- Popup blen 29 | pumheight = 10, -- pop up menu height 30 | relativenumber = true, -- set relative numbered lines 31 | scrolloff = 10, -- is one of my fav 32 | sessionoptions = 'blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal', 33 | shiftround = true, -- Round indent 34 | shiftwidth = 4, -- the number of spaces inserted for each indentation 35 | showcmd = false, 36 | showmode = false, -- we don't need to see things like -- INSERT -- anymore 37 | showtabline = 0, -- always show tabs 38 | si = true, 39 | sidescrolloff = 8, 40 | signcolumn = 'yes', -- always show the sign column, otherwise it would shift the text each time 41 | smartcase = true, -- smart case 42 | smartindent = true, -- make indenting smarter again 43 | smarttab = true, 44 | splitbelow = true, -- force all horizontal splits to go below current window 45 | splitright = true, -- force all vertical splits to go to the right of current window 46 | swapfile = false, -- creates a swapfile 47 | tabstop = 4, -- insert 2 spaces for a tab 48 | termguicolors = true, -- set term gui colors (most terminals support this) 49 | timeoutlen = 300, -- time to wait for a mapped sequence to complete (in milliseconds) 50 | title = true, -- window titles 51 | undofile = true, -- enable persistent undo 52 | undodir = vim.fn.stdpath('cache') .. '/undo', 53 | undolevels = 10000, 54 | updatetime = 50, -- faster completion (4000ms default) 55 | wildmenu = true, -- wildmenu 56 | wildmode = 'longest:full,full', -- Command-line completion mode 57 | winminwidth = 5, -- Minimum window width 58 | wrap = false, -- display lines as one long line 59 | writebackup = false, -- do not edit backups 60 | } 61 | 62 | for k, v in pairs(options) do 63 | vim.opt[k] = v 64 | end 65 | 66 | -- netrw file explorer settings 67 | vim.g.netrw_winsize = 20 68 | vim.g.netrw_banner = 0 69 | vim.g.netrw_liststyle = 1 70 | 71 | -- Fix markdown indentation settings 72 | vim.g.markdown_recommended_style = 0 73 | 74 | vim.opt.path:append({ '**' }) 75 | vim.opt.shortmess:append({ W = true, I = true, c = true }) 76 | 77 | -- hides `~` at the end of the buffer 78 | vim.cmd([[set fillchars+=eob:\ ]]) 79 | 80 | vim.cmd([[ 81 | setlocal spell spelllang=en "Set spellcheck language to en 82 | setlocal spell! "Disable spell checks by default 83 | filetype plugin indent on 84 | if has('win32') 85 | let g:python3_host_prog = $HOME . '/scoop/apps/python/current/python.exe' 86 | endif 87 | let &t_Cs = "\e[4:3m" "Undercurl 88 | let &t_Ce = "\e[4:0m" 89 | set whichwrap+=<,>,[,],h,l 90 | set iskeyword+=- 91 | ]]) 92 | -------------------------------------------------------------------------------- /lua/lib/icons.lua: -------------------------------------------------------------------------------- 1 | return { 2 | diagnostics = { 3 | Error = ' ', 4 | Hint = '󰠠 ', 5 | Information = ' ', 6 | Question = ' ', 7 | Warning = ' ', 8 | }, 9 | documents = { 10 | File = ' ', 11 | FileEmpty = ' ', 12 | Files = ' ', 13 | Folder = ' ', 14 | FolderEmpty = ' ', 15 | OpenFolder = ' ', 16 | OpenFolderEmpty = ' ', 17 | SymLink = ' ', 18 | SymlinkFolder = ' ', 19 | Import = ' ', 20 | }, 21 | git = { 22 | Add = ' ', 23 | AddAlt = ' ', 24 | Branch = ' ', 25 | Diff = ' ', 26 | DiffAlt = ' ', 27 | Ignore = '◌ ', 28 | Mod = ' ', 29 | Octoface = ' ', 30 | Remove = ' ', 31 | RemoveAlt = ' ', 32 | Rename = ' ', 33 | Repo = ' ', 34 | Tag = ' ', 35 | Untrack = ' ', 36 | Directory = '', 37 | }, 38 | kind = { 39 | Class = ' ', 40 | Color = ' ', 41 | Constant = ' ', 42 | Constructor = '󰈏 ', 43 | Copilot = ' ', 44 | Enum = ' ', 45 | EnumMember = ' ', 46 | Event = ' ', 47 | Field = ' ', 48 | File = ' ', 49 | Folder = ' ', 50 | Function = '󰊕 ', 51 | Interface = ' ', 52 | Keyword = ' ', 53 | Method = ' ', 54 | Module = '', 55 | Operator = ' ', 56 | Property = ' ', 57 | Reference = ' ', 58 | Snippet = ' ', 59 | Struct = ' ', 60 | Text = ' ', 61 | TypeParameter = ' ', 62 | Unit = ' ', 63 | Value = ' ', 64 | Variable = ' ', 65 | }, 66 | type = { 67 | Array = ' ', 68 | Boolean = '⏻ ', 69 | Number = ' ', 70 | Object = ' ', 71 | String = ' ', 72 | }, 73 | ui = { 74 | Arrow = ' ', 75 | ArrowClosed = ' ', 76 | ArrowLeft = ' ', 77 | ArrowOpen = ' ', 78 | ArrowRight = ' ', 79 | Bluetooth = ' ', 80 | Bookmark = ' ', 81 | Bug = ' ', 82 | Calendar = ' ', 83 | Camera = ' ', 84 | Check = ' ', 85 | ChevronRight = '', 86 | Circle = ' ', 87 | CircleSmall = '● ', 88 | CircleSmallEmpty = '○ ', 89 | Clipboard = ' ', 90 | Close = ' ', 91 | Code = ' ', 92 | Collection = ' ', 93 | Color = ' ', 94 | Command = ' ', 95 | Comment = ' ', 96 | Copilot = ' ', 97 | CopilotError = ' ', 98 | Corner = '└ ', 99 | Dashboard = ' ', 100 | Database = ' ', 101 | Download = ' ', 102 | Edit = ' ', 103 | Edge = '│ ', 104 | Electric = ' ', 105 | Eye = ' ', 106 | Fire = ' ', 107 | Firefox = ' ', 108 | Flag = ' ', 109 | Game = ' ', 110 | Gear = ' ', 111 | GitHub = ' ', 112 | Heart = ' ', 113 | History = ' ', 114 | Home = ' ', 115 | Incoming = ' ', 116 | Jump = ' ', 117 | Keyboard = ' ', 118 | Ligthbulb = '󰌵 ', 119 | List = '', 120 | Lock = ' ', 121 | Minus = '‒ ', 122 | Music = '󰝚 ', 123 | Neovim = ' ', 124 | NewFile = ' ', 125 | None = ' ', 126 | Note = ' ', 127 | Outgoing = ' ', 128 | Package = ' ', 129 | Paint = ' ', 130 | Pause = ' ', 131 | Pencil = ' ', 132 | Person = ' ', 133 | Pin = ' ', 134 | Play = ' ', 135 | Plug = ' ', 136 | Plus = ' ', 137 | Power = ' ', 138 | PowerlineArrowLeft = '', 139 | PowerlineArrowRight = '', 140 | PowerlineLeftRound = '', 141 | PowerlineRightRound = '', 142 | Project = ' ', 143 | Question = ' ', 144 | Reload = ' ', 145 | Rocket = ' ', 146 | Save = '󰆓 ', 147 | Search = ' ', 148 | Separator = '▊ ', 149 | SeparatorLight = '▍', 150 | SeparatorDashed = '┆', 151 | SignIn = ' ', 152 | SignOut = ' ', 153 | Sleep = '󰒲 ', 154 | Star = ' ', 155 | Table = ' ', 156 | Telescope = ' ', 157 | Terminal = ' ', 158 | Test = ' ', 159 | Time = ' ', 160 | Topline = '‾', 161 | Trash = ' ', 162 | User = ' ', 163 | Vim = ' ', 164 | Wifi = ' ', 165 | Windows = ' ', 166 | }, 167 | } 168 | -------------------------------------------------------------------------------- /lua/lib/prompts.lua: -------------------------------------------------------------------------------- 1 | local prompts = { 2 | docs = 'Generate comprehensive documentation for this code including parameters, return values, and usage examples.', 3 | explain = 'Explain this code in detail, including its purpose, logic flow, and any algorithms used.', 4 | fix = 'Identify and fix any bugs, errors, or code smells in this code.', 5 | commit = 'Create a descriptive commit message following conventional commits format for these changes.', 6 | optimize = 'Optimize this code for better performance, readability, and maintainability.', 7 | review = 'Review this code for best practices, potential issues, and suggest improvements.', 8 | tests = 'Write comprehensive unit tests covering all edge cases for this code.', 9 | } 10 | 11 | ---Returns a function that inserts the named prompt at cursor position 12 | ---@param prompt_name string Name of the prompt to insert 13 | ---@return function Function to execute in a keybinding 14 | prompts.add_prompt = function(prompt_name) 15 | local prompt_text = prompts[prompt_name] 16 | return function() 17 | vim.cmd("put ='" .. prompt_text:gsub("'", "''") .. "'") 18 | end 19 | end 20 | 21 | return prompts 22 | -------------------------------------------------------------------------------- /lua/lib/util.lua: -------------------------------------------------------------------------------- 1 | local util = {} 2 | 3 | util.get_user_config = function(key, default) 4 | local status_ok, user = pcall(require, 'user') 5 | if not status_ok then 6 | return default 7 | end 8 | 9 | local user_config = user[key] 10 | if user_config == nil then 11 | return default 12 | end 13 | return user_config 14 | end 15 | 16 | util.get_root_dir = function() 17 | local bufname = vim.fn.expand('%:p') 18 | if vim.fn.filereadable(bufname) == 0 then 19 | return 20 | end 21 | 22 | local parent = vim.fn.fnamemodify(bufname, ':h') 23 | local git_root = vim.fn.systemlist('git -C ' .. parent .. ' rev-parse --show-toplevel') 24 | if #git_root > 0 and git_root[1] ~= '' then 25 | return git_root[1] 26 | else 27 | return parent 28 | end 29 | end 30 | 31 | util.get_file_path = function() 32 | local buf_name = vim.api.nvim_buf_get_name(0) 33 | if vim.fn.filereadable(buf_name) == 1 then 34 | return buf_name 35 | end 36 | 37 | local dir_name = vim.fn.fnamemodify(buf_name, ':p:h') 38 | if vim.fn.isdirectory(dir_name) == 1 then 39 | return dir_name 40 | end 41 | 42 | return vim.loop.cwd() 43 | end 44 | 45 | util.get_file_type_cmd = function(extension) 46 | local root = util.get_root_dir() 47 | 48 | if extension == 'arb' and root then 49 | local gemfile_exists = vim.fn.filereadable(root .. '/Gemfile') == 1 50 | local pubspec_exists = vim.fn.filereadable(root .. '/pubspec.yaml') == 1 51 | if gemfile_exists then 52 | return 'setfiletype ruby' 53 | end 54 | if pubspec_exists then 55 | return 'setfiletype json' 56 | end 57 | end 58 | return '' 59 | end 60 | 61 | util.is_present = function(bin) 62 | return vim.fn.executable(bin) == 1 63 | end 64 | 65 | return util 66 | -------------------------------------------------------------------------------- /lua/plugins/ai/avante.lua: -------------------------------------------------------------------------------- 1 | local avante = require('avante') 2 | 3 | local model_names = { 4 | 'claude-3.5-sonnet', 5 | 'claude-3.7-sonnet', 6 | 'claude-3.7-sonnet-thought', 7 | 'gemini-2.0-flash-001', 8 | 'gemini-2.5-pro', 9 | 'gpt-4.1', 10 | 'gpt-4o-2024-11-20', 11 | 'o1', 12 | 'o3-mini', 13 | 'o4-mini', 14 | } 15 | 16 | avante.setup({ 17 | mode = 'agentic', 18 | provider = 'copilot-gemini-2.5-pro', 19 | -- cursor_applying_provider = 'copilot-o3-mini', 20 | -- auto_suggestions_provider = 'copilot-claude-3.7-sonnet', 21 | copilot = { 22 | endpoint = 'https://api.githubcopilot.com', 23 | allow_insecure = false, 24 | timeout = 10 * 60 * 1000, 25 | temperature = 0, 26 | max_completion_tokens = 1000000, 27 | reasoning_effort = 'high', 28 | }, 29 | 30 | vendors = (function() 31 | local vendors_table = {} 32 | for _, model_name in ipairs(model_names) do 33 | local vendor_key = 'copilot-' .. model_name 34 | vendors_table[vendor_key] = { 35 | __inherited_from = 'copilot', 36 | model = model_name, 37 | display_name = vendor_key, 38 | } 39 | end 40 | return vendors_table 41 | end)(), 42 | 43 | behaviour = { 44 | auto_suggestions = false, 45 | auto_set_highlight_group = true, 46 | auto_set_keymaps = true, 47 | auto_apply_diff_after_generation = false, 48 | support_paste_from_clipboard = false, 49 | minimize_diff = true, -- Whether to remove unchanged lines when applying a code block 50 | enable_token_counting = true, 51 | }, 52 | hints = { enabled = false }, 53 | mappings = { 54 | ---@class AvanteConflictMappings 55 | diff = { 56 | ours = 'co', 57 | theirs = 'ct', 58 | all_theirs = 'ca', 59 | both = 'cb', 60 | cursor = 'cc', 61 | next = ']x', 62 | prev = '[x', 63 | }, 64 | suggestion = { 65 | accept = '', 66 | next = '', 67 | prev = '', 68 | dismiss = '', 69 | }, 70 | jump = { 71 | next = ']]', 72 | prev = '[[', 73 | }, 74 | submit = { 75 | normal = '', 76 | insert = '', 77 | }, 78 | cancel = { 79 | normal = { '', '', 'q' }, 80 | insert = { '' }, 81 | }, 82 | ask = 'aa', 83 | edit = 'ae', 84 | refresh = 'ar', 85 | focus = 'af', 86 | stop = 'as', 87 | select_model = 'aM', 88 | select_history = 'ah', 89 | files = { 90 | add_current = 'ac', 91 | add_all_buffers = 'ab', 92 | }, 93 | toggle = { 94 | default = 'at', 95 | debug = 'ad', 96 | hint = 'aH', 97 | suggestion = 'aS', 98 | repomap = 'aR', 99 | }, 100 | sidebar = { 101 | apply_all = 'A', 102 | apply_cursor = 'a', 103 | retry_user_request = 'r', 104 | edit_user_request = 'e', 105 | switch_windows = '', 106 | reverse_switch_windows = '', 107 | remove_file = 'd', 108 | add_file = 'a', 109 | close = { 'q' }, 110 | close_from_input = nil, -- e.g., { normal = "", insert = "" } 111 | }, 112 | }, 113 | windows = { 114 | ---@type "right" | "left" | "top" | "bottom" 115 | position = 'right', 116 | wrap = true, 117 | width = 40, 118 | sidebar_header = { 119 | enabled = true, 120 | align = 'center', 121 | rounded = true, 122 | }, 123 | input = { 124 | prefix = '> ', 125 | height = 32, 126 | }, 127 | edit = { 128 | border = 'rounded', 129 | start_insert = true, 130 | }, 131 | ask = { 132 | floating = false, 133 | start_insert = true, 134 | border = 'rounded', 135 | ---@type "ours" | "theirs" 136 | focus_on_apply = 'ours', 137 | }, 138 | }, 139 | highlights = { 140 | diff = { 141 | current = 'DiffText', 142 | incoming = 'DiffAdd', 143 | }, 144 | }, 145 | --- @class AvanteConflictUserConfig 146 | diff = { 147 | autojump = true, 148 | ---@type string | fun(): any 149 | list_opener = 'copen', 150 | override_timeoutlen = 500, 151 | }, 152 | suggestion = { 153 | debounce = 600, 154 | throttle = 600, 155 | }, 156 | system_prompt = function() 157 | local hub = require('mcphub').get_hub_instance() 158 | return hub:get_active_servers_prompt() 159 | end, 160 | custom_tools = function() 161 | return { 162 | require('mcphub.extensions.avante').mcp_tool(), 163 | } 164 | end, 165 | disabled_tools = {}, 166 | slash_commands = {}, 167 | }) 168 | -------------------------------------------------------------------------------- /lua/plugins/ai/copilot.lua: -------------------------------------------------------------------------------- 1 | local copilot = require('copilot') 2 | 3 | copilot.setup({ 4 | panel = { 5 | enabled = true, 6 | auto_refresh = false, 7 | keymap = { 8 | jump_prev = '[[', 9 | jump_next = ']]', 10 | accept = '', 11 | refresh = 'gr', 12 | open = '', 13 | }, 14 | layout = { 15 | position = 'bottom', 16 | ratio = 0.4, 17 | }, 18 | }, 19 | suggestion = { 20 | enabled = true, 21 | auto_trigger = false, 22 | debounce = 75, 23 | keymap = { 24 | accept = '', 25 | accept_word = false, 26 | accept_line = false, 27 | next = '', 28 | prev = '', 29 | dismiss = '', 30 | }, 31 | }, 32 | filetypes = { 33 | yaml = true, 34 | markdown = true, 35 | help = true, 36 | gitcommit = true, 37 | gitrebase = true, 38 | hgcommit = true, 39 | svn = true, 40 | cvs = true, 41 | ['.'] = true, 42 | }, 43 | copilot_node_command = 'node', -- Node.js version must be > 16.x 44 | server_opts_overrides = {}, 45 | }) 46 | -------------------------------------------------------------------------------- /lua/plugins/ai/mcphub.lua: -------------------------------------------------------------------------------- 1 | local mcphub = require('mcphub') 2 | 3 | mcphub.setup({ 4 | port = 37373, 5 | config = vim.fn.expand('~/.config/mcphub/servers.json'), 6 | native_servers = {}, 7 | 8 | auto_approve = false, 9 | auto_toggle_mcp_servers = true, 10 | extensions = { 11 | avante = { 12 | make_slash_commands = true, 13 | }, 14 | }, 15 | 16 | ui = { 17 | window = { 18 | width = 0.8, 19 | height = 0.8, 20 | relative = 'editor', 21 | zindex = 50, 22 | border = 'rounded', 23 | }, 24 | wo = {}, 25 | }, 26 | 27 | on_ready = function(hub) end, 28 | on_error = function(err) end, 29 | 30 | use_bundled_binary = true, 31 | 32 | -- server_url = nil, -- defaults to `http://localhost:port` 33 | shutdown_delay = 600000, -- 10 minutes 34 | log = { 35 | level = vim.log.levels.INFO, 36 | to_file = true, 37 | file_path = vim.fn.stdpath('state') .. '/mcphub.log', 38 | prefix = 'MCPHub', 39 | }, 40 | }) 41 | -------------------------------------------------------------------------------- /lua/plugins/editor/ai.lua: -------------------------------------------------------------------------------- 1 | local ai = require('mini.ai') 2 | 3 | ai.setup({ 4 | custom_textobjects = { 5 | o = ai.gen_spec.treesitter({ 6 | a = { '@block.outer', '@conditional.outer', '@loop.outer' }, 7 | i = { '@block.inner', '@conditional.inner', '@loop.inner' }, 8 | }, {}), 9 | f = ai.gen_spec.treesitter({ a = '@function.outer', i = '@function.inner' }, {}), 10 | c = ai.gen_spec.treesitter({ a = '@class.outer', i = '@class.inner' }, {}), 11 | t = { '<([%p%w]-)%f[^<%w][^<>]->.-', '^<.->().*()$' }, 12 | }, 13 | 14 | mappings = { 15 | -- Main textobject prefixes 16 | around = 'a', 17 | inside = 'i', 18 | 19 | -- Next/last variants 20 | around_next = 'an', 21 | inside_next = 'in', 22 | around_last = 'al', 23 | inside_last = 'il', 24 | 25 | -- Move cursor to corresponding edge of `a` textobject 26 | goto_left = 'g[', 27 | goto_right = 'g]', 28 | }, 29 | 30 | -- How to search for object 31 | -- 'cover', 'cover_or_next', 'cover_or_prev','cover_or_nearest', 'next', 'previous', 'nearest'. 32 | search_method = 'cover_or_next', 33 | n_lines = 500, 34 | silent = false, 35 | }) 36 | -------------------------------------------------------------------------------- /lua/plugins/editor/bracketed.lua: -------------------------------------------------------------------------------- 1 | local bracketed = require('mini.bracketed') 2 | 3 | bracketed.setup({ 4 | buffer = { suffix = 'b', options = {} }, 5 | comment = { suffix = 'c', options = {} }, 6 | conflict = { suffix = 'x', options = {} }, 7 | diagnostic = { suffix = 'd', options = {} }, 8 | file = { suffix = 'f', options = {} }, 9 | indent = { suffix = 'i', options = {} }, 10 | jump = { suffix = 'j', options = {} }, 11 | location = { suffix = 'l', options = {} }, 12 | oldfile = { suffix = 'r', options = {} }, 13 | quickfix = { suffix = 'q', options = {} }, 14 | treesitter = { suffix = 'n', options = {} }, 15 | undo = { suffix = 'u', options = {} }, 16 | window = { suffix = 'w', options = {} }, 17 | yank = { suffix = 'y', options = {} }, 18 | }) 19 | -------------------------------------------------------------------------------- /lua/plugins/editor/pairs.lua: -------------------------------------------------------------------------------- 1 | local pairs = require('mini.pairs') 2 | 3 | pairs.setup({ 4 | modes = { insert = true, command = true, terminal = false }, 5 | mappings = { 6 | ['('] = { action = 'open', pair = '()', neigh_pattern = '[^\\].' }, 7 | ['['] = { action = 'open', pair = '[]', neigh_pattern = '[^\\].' }, 8 | ['{'] = { action = 'open', pair = '{}', neigh_pattern = '[^\\].' }, 9 | 10 | [')'] = { action = 'close', pair = '()', neigh_pattern = '[^\\].' }, 11 | [']'] = { action = 'close', pair = '[]', neigh_pattern = '[^\\].' }, 12 | ['}'] = { action = 'close', pair = '{}', neigh_pattern = '[^\\].' }, 13 | 14 | ['"'] = { action = 'closeopen', pair = '""', neigh_pattern = '[^\\].', register = { cr = false } }, 15 | ["'"] = { action = 'closeopen', pair = "''", neigh_pattern = '[^%a\\].', register = { cr = false } }, 16 | ['`'] = { action = 'closeopen', pair = '``', neigh_pattern = '[^\\].', register = { cr = false } }, 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /lua/plugins/editor/spider.lua: -------------------------------------------------------------------------------- 1 | local spider = require('spider') 2 | 3 | spider.setup({ 4 | skipInsignificantPunctuation = true, 5 | }) 6 | 7 | vim.keymap.set({ 'n', 'o', 'x' }, 'w', "lua require('spider').motion('w')", { desc = 'Spider-w' }) 8 | vim.keymap.set({ 'n', 'o', 'x' }, 'e', "lua require('spider').motion('e')", { desc = 'Spider-e' }) 9 | vim.keymap.set({ 'n', 'o', 'x' }, 'b', "lua require('spider').motion('b')", { desc = 'Spider-b' }) 10 | vim.keymap.set({ 'n', 'o', 'x' }, 'ge', "lua require('spider').motion('ge')", { desc = 'Spider-ge' }) 11 | -------------------------------------------------------------------------------- /lua/plugins/editor/surround.lua: -------------------------------------------------------------------------------- 1 | local surround = require('mini.surround') 2 | 3 | surround.setup({ 4 | custom_surroundings = nil, 5 | mappings = { 6 | add = 'gsa', 7 | delete = 'gsd', 8 | find = 'gsf', 9 | find_left = 'gsF', 10 | highlight = 'gsh', 11 | replace = 'gsr', 12 | update_n_lines = 'gsn', 13 | 14 | suffix_last = 'l', -- Suffix to search with "prev" method 15 | suffix_next = 'n', -- Suffix to search with "next" method 16 | }, 17 | 18 | -- How to search for surrounding 19 | -- 'cover', 'cover_or_next', 'cover_or_prev','cover_or_nearest', 'next', 'previous', 'nearest'. 20 | search_method = 'cover_or_nearest', 21 | highlight_duration = 500, 22 | n_lines = 20, 23 | respect_selection_type = false, 24 | silent = false, 25 | }) 26 | -------------------------------------------------------------------------------- /lua/plugins/editor/textobjects.lua: -------------------------------------------------------------------------------- 1 | local textobjects = { 2 | select = { 3 | enable = true, 4 | lookahead = true, 5 | 6 | keymaps = { 7 | ['a='] = { query = '@assignment.outer', desc = 'Select outer part of an assignment' }, 8 | ['i='] = { query = '@assignment.inner', desc = 'Select inner part of an assignment' }, 9 | ['al='] = { query = '@assignment.lhs', desc = 'Select left hand side of an assignment' }, 10 | ['ar='] = { 11 | query = '@assignment.rhs', 12 | desc = 'Select right hand side of an assignment', 13 | }, 14 | 15 | ['a:'] = { query = '@property.outer', desc = 'Select outer part of an object property' }, 16 | ['i:'] = { query = '@property.inner', desc = 'Select inner part of an object property' }, 17 | ['l:'] = { query = '@property.lhs', desc = 'Select left part of an object property' }, 18 | ['r:'] = { query = '@property.rhs', desc = 'Select right part of an object property' }, 19 | 20 | ['aa'] = { 21 | query = '@parameter.outer', 22 | desc = 'Select outer part of a parameter/argument', 23 | }, 24 | ['ia'] = { 25 | query = '@parameter.inner', 26 | desc = 'Select inner part of a parameter/argument', 27 | }, 28 | 29 | ['ai'] = { query = '@conditional.outer', desc = 'Select outer part of a conditional' }, 30 | ['ii'] = { query = '@conditional.inner', desc = 'Select inner part of a conditional' }, 31 | 32 | ['al'] = { query = '@loop.outer', desc = 'Select outer part of a loop' }, 33 | ['il'] = { query = '@loop.inner', desc = 'Select inner part of a loop' }, 34 | 35 | ['af'] = { query = '@call.outer', desc = 'Select outer part of a function call' }, 36 | ['if'] = { query = '@call.inner', desc = 'Select inner part of a function call' }, 37 | 38 | ['am'] = { 39 | query = '@function.outer', 40 | desc = 'Select outer part of a method/function definition', 41 | }, 42 | ['im'] = { 43 | query = '@function.inner', 44 | desc = 'Select inner part of a method/function definition', 45 | }, 46 | 47 | ['ac'] = { query = '@class.outer', desc = 'Select outer part of a class' }, 48 | ['ic'] = { query = '@class.inner', desc = 'Select inner part of a class' }, 49 | }, 50 | }, 51 | swap = { 52 | enable = true, 53 | swap_next = { 54 | ['rna'] = '@parameter.inner', -- swap object property with next 55 | ['rn:'] = '@property.outer', -- swap parameters/argument with next 56 | ['rnm'] = '@function.outer', -- swap function with next 57 | }, 58 | swap_previous = { 59 | ['rpa'] = '@parameter.inner', -- swap parameters/argument with prev 60 | ['rp:'] = '@property.outer', -- swap object property with prev 61 | ['rpm'] = '@function.outer', -- swap function with previous 62 | }, 63 | }, 64 | move = { 65 | enable = true, 66 | set_jumps = true, -- whether to set jumps in the jumplist 67 | goto_previous_start = { 68 | ['[oc'] = { query = '@class.outer', desc = 'Prev class start' }, 69 | ['[of'] = { query = '@call.outer', desc = 'Prev function call start' }, 70 | ['[oi'] = { query = '@conditional.outer', desc = 'Prev conditional start' }, 71 | ['[ol'] = { query = '@loop.outer', desc = 'Prev loop start' }, 72 | ['[om'] = { query = '@function.outer', desc = 'Prev method def start' }, 73 | ['[z'] = { query = '@fold', query_group = 'folds', desc = 'Prev fold' }, 74 | -- You can pass a query group to use query from `queries//.scm file in your runtime path. 75 | -- Above example nvim-treesitter's folds.scm`. They also provide locals.scm, highlights.scm and indent.scm. 76 | }, 77 | goto_previous_end = { 78 | ['[oC'] = { query = '@class.outer', desc = 'Prev class end' }, 79 | ['[oF'] = { query = '@call.outer', desc = 'Prev function call end' }, 80 | ['[oI'] = { query = '@conditional.outer', desc = 'Prev conditional end' }, 81 | ['[oL'] = { query = '@loop.outer', desc = 'Prev loop end' }, 82 | ['[oM'] = { query = '@function.outer', desc = 'Prev method def end' }, 83 | ['[Z'] = { query = '@fold', query_group = 'folds', desc = 'Prev fold end' }, 84 | }, 85 | goto_next_start = { 86 | [']oc'] = { query = '@class.outer', desc = 'Next class start' }, 87 | [']of'] = { query = '@call.outer', desc = 'Next function call start' }, 88 | [']oi'] = { query = '@conditional.outer', desc = 'Next conditional start' }, 89 | [']ol'] = { query = '@loop.outer', desc = 'Next loop start' }, 90 | [']om'] = { query = '@function.outer', desc = 'Next method def start' }, 91 | [']z'] = { query = '@fold', query_group = 'folds', desc = 'Next fold' }, 92 | }, 93 | goto_next_end = { 94 | [']oC'] = { query = '@class.outer', desc = 'Next class end' }, 95 | [']oF'] = { query = '@call.outer', desc = 'Next function call end' }, 96 | [']oI'] = { query = '@conditional.outer', desc = 'Next conditional end' }, 97 | [']oL'] = { query = '@loop.outer', desc = 'Next loop end' }, 98 | [']oM'] = { query = '@function.outer', desc = 'Next method def end' }, 99 | [']Z'] = { query = '@fold', query_group = 'folds', desc = 'Next fold end' }, 100 | }, 101 | }, 102 | } 103 | 104 | local ts_repeat_move = require('nvim-treesitter.textobjects.repeatable_move') 105 | 106 | -- vim way: ; goes to the direction you were moving. 107 | vim.keymap.set({ 'n', 'x', 'o' }, ';', ts_repeat_move.repeat_last_move) 108 | vim.keymap.set({ 'n', 'x', 'o' }, ',', ts_repeat_move.repeat_last_move_opposite) 109 | 110 | -- Optionally, make builtin f, F, t, T also repeatable with ; and , 111 | vim.keymap.set({ 'n', 'x', 'o' }, 'f', ts_repeat_move.builtin_f) 112 | vim.keymap.set({ 'n', 'x', 'o' }, 'F', ts_repeat_move.builtin_F) 113 | vim.keymap.set({ 'n', 'x', 'o' }, 't', ts_repeat_move.builtin_t) 114 | vim.keymap.set({ 'n', 'x', 'o' }, 'T', ts_repeat_move.builtin_T) 115 | 116 | return textobjects 117 | -------------------------------------------------------------------------------- /lua/plugins/editor/treesitter.lua: -------------------------------------------------------------------------------- 1 | local treesitter = require('nvim-treesitter.configs') 2 | local textobjects = require('plugins.editor.textobjects') 3 | 4 | local auto_install = require('lib.util').get_user_config('auto_install', true) 5 | local installed_parsers = {} 6 | if auto_install then 7 | installed_parsers = require('plugins.list').ts_parsers 8 | end 9 | 10 | treesitter.setup({ 11 | ensure_installed = installed_parsers, 12 | sync_install = false, 13 | ignore_install = {}, 14 | auto_install = true, 15 | 16 | textobjects = textobjects, 17 | matchup = { enable = true }, 18 | indent = { enable = true }, 19 | 20 | highlight = { 21 | enable = true, 22 | disable = function(lang, buf) 23 | local max_filesize = 100 * 1024 -- 100 KB 24 | local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) 25 | if ok and stats and stats.size > max_filesize then 26 | return true 27 | end 28 | end, 29 | additional_vim_regex_highlighting = false, 30 | }, 31 | 32 | incremental_selection = { 33 | enable = true, 34 | keymaps = { 35 | init_selection = '', 36 | node_incremental = '', 37 | scope_incremental = false, 38 | node_decremental = '', 39 | }, 40 | }, 41 | 42 | textsubjects = { 43 | enable = true, 44 | prev_selection = ',', 45 | keymaps = { 46 | ['.'] = { 'textsubjects-smart', desc = 'Select the current text subject' }, 47 | ['a;'] = { 48 | 'textsubjects-container-outer', 49 | desc = 'Select outer container (class, function, etc.)', 50 | }, 51 | ['i;'] = { 52 | 'textsubjects-container-inner', 53 | desc = 'Select inside containers (classes, functions, etc.)', 54 | }, 55 | }, 56 | }, 57 | 58 | refactor = { 59 | highlight_definitions = { 60 | enable = true, 61 | clear_on_cursor_move = true, 62 | }, 63 | highlight_current_scope = { enable = true }, 64 | smart_rename = { 65 | enable = true, 66 | keymaps = { 67 | smart_rename = 'rr', 68 | }, 69 | }, 70 | navigation = { 71 | enable = true, 72 | keymaps = { 73 | goto_definition = 'rd', 74 | list_definitions = 'rl', 75 | list_definitions_toc = 'rh', 76 | goto_next_usage = 'rj', 77 | goto_previous_usage = 'rk', 78 | }, 79 | }, 80 | }, 81 | }) 82 | -------------------------------------------------------------------------------- /lua/plugins/lang/blink.lua: -------------------------------------------------------------------------------- 1 | local blink = require('blink.cmp') 2 | local icons = require('lib.icons') 3 | 4 | blink.setup({ 5 | -- 'default', 'super-tab', 'enter' 6 | keymap = { 7 | preset = 'enter', 8 | [''] = { 'select_next', 'snippet_forward', 'fallback' }, 9 | [''] = { 'select_prev', 'snippet_backward', 'fallback' }, 10 | [''] = { 'show', 'hide' }, 11 | [''] = { 'show_documentation', 'hide_documentation' }, 12 | }, 13 | completion = { 14 | list = { 15 | selection = { 16 | auto_insert = true, 17 | preselect = true, 18 | }, 19 | }, 20 | menu = { border = 'rounded' }, 21 | documentation = { window = { border = 'rounded' } }, 22 | }, 23 | signature = { window = { border = 'rounded' } }, 24 | appearance = { 25 | -- Sets the fallback highlight groups to nvim-cmp's highlight groups 26 | use_nvim_cmp_as_default = true, 27 | -- Set to 'mono' for 'Nerd Font Mono' or 'normal' for 'Nerd Font' 28 | nerd_font_variant = 'normal', 29 | kind_icons = icons.kind, 30 | }, 31 | sources = { 32 | default = { 'avante', 'lazydev', 'lsp', 'path', 'snippets', 'buffer', 'copilot' }, 33 | providers = { 34 | avante = { 35 | module = 'blink-cmp-avante', 36 | name = 'Avante', 37 | opts = {}, 38 | }, 39 | copilot = { 40 | name = 'copilot', 41 | module = 'blink-cmp-copilot', 42 | score_offset = 90, 43 | async = true, 44 | transform_items = function(_, items) 45 | local CompletionItemKind = require('blink.cmp.types').CompletionItemKind 46 | local kind_idx = #CompletionItemKind + 1 47 | CompletionItemKind[kind_idx] = 'Copilot' 48 | for _, item in ipairs(items) do 49 | item.kind = kind_idx 50 | end 51 | return items 52 | end, 53 | }, 54 | lazydev = { 55 | name = 'LazyDev', 56 | module = 'lazydev.integrations.blink', 57 | -- make lazydev completions top priority (see `:h blink.cmp`) 58 | score_offset = 100, 59 | }, 60 | }, 61 | }, 62 | }) 63 | -------------------------------------------------------------------------------- /lua/plugins/lang/lspconfig.lua: -------------------------------------------------------------------------------- 1 | local lspconfig = require('lspconfig') 2 | local icons = require('lib.icons').diagnostics 3 | 4 | local auto_install = require('lib.util').get_user_config('auto_install', true) 5 | local installed_servers = {} 6 | if auto_install then 7 | installed_servers = require('plugins.list').lsp_servers 8 | end 9 | 10 | local capabilities = require('blink.cmp').get_lsp_capabilities() 11 | local default_setup = function(server) 12 | lspconfig[server].setup({ 13 | capabilities = capabilities, 14 | }) 15 | end 16 | 17 | require('mason-lspconfig').setup({ 18 | ensure_installed = installed_servers, 19 | handlers = { default_setup }, 20 | }) 21 | 22 | local signs = { Error = icons.Error, Warn = icons.Warning, Hint = icons.Hint, Info = icons.Information } 23 | vim.diagnostic.config({ 24 | underline = true, 25 | update_in_insert = true, 26 | severity_sort = true, 27 | virtual_text = true, 28 | float = true, 29 | signs = { 30 | text = { 31 | [vim.diagnostic.severity.ERROR] = signs.Error, 32 | [vim.diagnostic.severity.WARN] = signs.Warn, 33 | [vim.diagnostic.severity.INFO] = signs.Info, 34 | [vim.diagnostic.severity.HINT] = signs.Hint, 35 | }, 36 | }, 37 | }) 38 | -------------------------------------------------------------------------------- /lua/plugins/lang/lspsaga.lua: -------------------------------------------------------------------------------- 1 | local lspsaga = require('lspsaga') 2 | 3 | local icons = require('lib.icons') 4 | 5 | lspsaga.setup({ 6 | ui = { 7 | theme = 'round', 8 | border = 'rounded', 9 | devicon = true, 10 | title = true, 11 | winblend = 1, 12 | expand = icons.ui.ArrowOpen, 13 | collapse = icons.ui.ArrowClosed, 14 | preview = icons.ui.List, 15 | code_action = icons.diagnostics.Hint, 16 | diagnostic = icons.ui.Bug, 17 | incoming = icons.ui.Incoming, 18 | outgoing = icons.ui.Outgoing, 19 | hover = icons.ui.Comment, 20 | }, 21 | }) 22 | -------------------------------------------------------------------------------- /lua/plugins/lang/mason.lua: -------------------------------------------------------------------------------- 1 | local mason = require('mason') 2 | 3 | local icons = require('lib.icons') 4 | mason.setup({ 5 | -- - "prepend": Use mason binary, "append": Use system binary 6 | PATH = 'append', 7 | 8 | log_level = vim.log.levels.INFO, 9 | max_concurrent_installers = 8, 10 | 11 | ui = { 12 | check_outdated_packages_on_open = true, 13 | border = 'rounded', 14 | width = 0.8, 15 | height = 0.8, 16 | 17 | icons = { 18 | package_installed = icons.ui.Gear, 19 | package_pending = icons.ui.Download, 20 | package_uninstalled = icons.ui.Plus, 21 | }, 22 | 23 | keymaps = { 24 | toggle_package_expand = '', 25 | install_package = 'i', 26 | update_package = 'u', 27 | check_package_version = 'c', 28 | update_all_packages = 'U', 29 | check_outdated_packages = 'C', 30 | uninstall_package = 'x', 31 | cancel_installation = '', 32 | apply_language_filter = '', 33 | }, 34 | }, 35 | }) 36 | -------------------------------------------------------------------------------- /lua/plugins/lang/null-ls.lua: -------------------------------------------------------------------------------- 1 | local null_ls = require('null-ls') 2 | 3 | local action = null_ls.builtins.code_actions 4 | local comp = null_ls.builtins.completion 5 | local diag = null_ls.builtins.diagnostics 6 | local format = null_ls.builtins.formatting 7 | local hover = null_ls.builtins.hover 8 | 9 | -- Buily in sources: https://github.com/nvimtools/none-ls.nvim/blob/main/doc/BUILTINS.md 10 | null_ls.setup({ 11 | debug = false, 12 | border = 'rounded', 13 | log_level = 'info', 14 | diagnostics_format = '#{c} #{m} (#{s})', 15 | sources = { 16 | action.proselint, -- markdown actions 17 | -- action.ts_node_action, -- treesitter node actions, buggy, causes repeated notifications 18 | comp.spell, -- spell completion 19 | comp.tags, -- tags completion 20 | diag.actionlint, -- github action lint 21 | diag.credo, -- elixir diagnostics 22 | diag.golangci_lint, 23 | diag.hadolint, -- docker lint 24 | diag.proselint, -- markdown lint 25 | diag.reek, -- ruby code smell 26 | -- diag.rubocop, -- ruby diagnostics 27 | -- diag.todo_comments, -- causes highlighter errors on J 28 | diag.trail_space, -- trailing space check 29 | diag.vint, -- vim lint 30 | diag.write_good, -- english writing style 31 | format.mix, -- elixir formatter 32 | format.prettier, -- js, md, css, etc formatter 33 | -- format.rubocop, -- ruby formatter 34 | format.shfmt, -- shell formatter 35 | format.stylua, -- lua formatter 36 | hover.dictionary, -- show word dictionary on hover 37 | hover.printenv, -- show env on hover 38 | }, 39 | }) 40 | 41 | local auto_install = require('lib.util').get_user_config('auto_install', true) 42 | local installed_sources = {} 43 | if auto_install then 44 | installed_sources = require('plugins.list').null_ls_sources 45 | end 46 | 47 | require('mason-null-ls').setup({ 48 | ensure_installed = installed_sources, 49 | automatic_installation = auto_install, 50 | }) 51 | -------------------------------------------------------------------------------- /lua/plugins/lazy.lua: -------------------------------------------------------------------------------- 1 | local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' 2 | if not vim.loop.fs_stat(lazypath) then 3 | vim.fn.system({ 4 | 'git', 5 | 'clone', 6 | '--filter=blob:none', 7 | '--single-branch', 8 | 'https://github.com/folke/lazy.nvim.git', 9 | lazypath, 10 | }) 11 | end 12 | vim.opt.runtimepath:prepend(lazypath) 13 | 14 | local status_ok, lazy = pcall(require, 'lazy') 15 | if not status_ok then 16 | return 17 | end 18 | 19 | local icons = require('lib.icons') 20 | local plugins = require('plugins.list').plugins 21 | 22 | lazy.setup({ 23 | root = vim.fn.stdpath('data') .. '/lazy', 24 | defaults = { lazy = true }, 25 | spec = plugins, 26 | lockfile = vim.fn.stdpath('config') .. '/lua/plugins/lock.json', 27 | concurrency = 8, 28 | dev = { path = '~/Projects/2KAbhishek/', patterns = { '2kabhishek' }, fallback = true }, 29 | install = { missing = true, colorscheme = { 'onedark' } }, 30 | 31 | git = { 32 | log = { '--since=3 days ago' }, 33 | timeout = 120, 34 | url_format = 'https://github.com/%s.git', 35 | filter = true, 36 | }, 37 | 38 | ui = { 39 | size = { width = 0.9, height = 0.8 }, 40 | wrap = true, 41 | border = 'rounded', 42 | icons = { 43 | cmd = icons.ui.Terminal, 44 | config = icons.ui.Gear, 45 | event = icons.ui.Electric, 46 | ft = icons.documents.File, 47 | init = icons.ui.Rocket, 48 | import = icons.documents.Import, 49 | keys = icons.ui.Keyboard, 50 | lazy = icons.ui.Sleep, 51 | loaded = icons.ui.CircleSmall, 52 | not_loaded = icons.ui.CircleSmallEmpty, 53 | plugin = icons.ui.Package, 54 | runtime = icons.ui.Neovim, 55 | source = icons.ui.Code, 56 | start = icons.ui.Play, 57 | task = icons.ui.Check, 58 | list = { 59 | icons.ui.CircleSmall, 60 | icons.ui.Arrow, 61 | icons.ui.Star, 62 | icons.ui.Minus, 63 | }, 64 | }, 65 | browser = nil, 66 | throttle = 20, 67 | custom_keys = { 68 | ['l'] = function(plugin) 69 | require('lazy.util').float_term({ 'lazygit', 'log' }, { 70 | cwd = plugin.dir, 71 | }) 72 | end, 73 | 74 | ['t'] = function(plugin) 75 | require('lazy.util').float_term(nil, { 76 | cwd = plugin.dir, 77 | }) 78 | end, 79 | }, 80 | }, 81 | 82 | diff = { cmd = 'git' }, 83 | checker = { enabled = false, concurrency = nil, notify = true, frequency = 3600 }, 84 | change_detection = { enabled = true, notify = true }, 85 | performance = { 86 | cache = { enabled = true }, 87 | reset_packpath = true, 88 | rtp = { 89 | reset = true, 90 | paths = {}, 91 | disabled_plugins = { 92 | 'gzip', 93 | 'tarPlugin', 94 | 'zipPlugin', 95 | 'tohtml', 96 | -- 'tutor', 97 | -- 'matchit', 98 | -- 'matchparen', 99 | -- 'netrwPlugin', 100 | }, 101 | }, 102 | }, 103 | readme = { 104 | root = vim.fn.stdpath('state') .. '/lazy/readme', 105 | files = { 'README.md', 'lua/**/README.md' }, 106 | skip_if_doc_exists = true, 107 | }, 108 | state = vim.fn.stdpath('state') .. '/lazy/state.json', 109 | }) 110 | -------------------------------------------------------------------------------- /lua/plugins/list.lua: -------------------------------------------------------------------------------- 1 | local util = require('lib.util') 2 | local function load_config(package) 3 | return function() 4 | require('plugins.' .. package) 5 | end 6 | end 7 | 8 | local plugins = { 9 | -- UI 10 | { 11 | 'navarasu/onedark.nvim', 12 | config = load_config('ui.onedark'), 13 | lazy = false, 14 | priority = 1000, 15 | }, 16 | { 'nvim-tree/nvim-web-devicons' }, 17 | { 18 | 'folke/snacks.nvim', 19 | priority = 1000, 20 | lazy = false, 21 | config = load_config('ui.snacks'), 22 | }, 23 | { 24 | 'nvim-lualine/lualine.nvim', 25 | config = load_config('ui.lualine'), 26 | event = { 'BufReadPost', 'BufNewFile' }, 27 | }, 28 | { 29 | 'folke/which-key.nvim', 30 | config = load_config('ui.which-key'), 31 | event = 'VeryLazy', 32 | }, 33 | { 34 | 'lewis6991/gitsigns.nvim', 35 | config = load_config('ui.gitsigns'), 36 | cmd = 'Gitsigns', 37 | event = { 'BufReadPost', 'BufNewFile' }, 38 | }, 39 | { 40 | '2kabhishek/markit.nvim', 41 | config = load_config('ui.markit'), 42 | event = { 'BufReadPost', 'BufNewFile' }, 43 | }, 44 | 45 | -- Editor 46 | { 47 | 'nvim-treesitter/nvim-treesitter', 48 | build = ':TSUpdate', 49 | dependencies = { 50 | 'nvim-treesitter/nvim-treesitter-refactor', 51 | 'nvim-treesitter/nvim-treesitter-textobjects', 52 | 'RRethy/nvim-treesitter-textsubjects', 53 | }, 54 | config = load_config('editor.treesitter'), 55 | event = { 'BufReadPost', 'BufNewFile' }, 56 | }, 57 | { 58 | 'echasnovski/mini.bracketed', 59 | config = load_config('editor.bracketed'), 60 | event = { 'BufReadPost', 'BufNewFile' }, 61 | }, 62 | { 63 | 'echasnovski/mini.pairs', 64 | config = load_config('editor.pairs'), 65 | event = 'InsertEnter', 66 | }, 67 | { 68 | 'echasnovski/mini.surround', 69 | version = '*', 70 | config = load_config('editor.surround'), 71 | event = { 'BufReadPost', 'BufNewFile' }, 72 | }, 73 | { 74 | 'echasnovski/mini.ai', 75 | version = '*', 76 | config = load_config('editor.ai'), 77 | event = { 'BufReadPost', 'BufNewFile' }, 78 | }, 79 | { 80 | 'chrisgrieser/nvim-spider', 81 | config = load_config('editor.spider'), 82 | event = { 'BufReadPost', 'BufNewFile' }, 83 | }, 84 | 85 | -- Language 86 | { 87 | 'neovim/nvim-lspconfig', 88 | dependencies = { 'williamboman/mason-lspconfig.nvim' }, 89 | config = load_config('lang.lspconfig'), 90 | event = { 'BufReadPre', 'BufNewFile' }, 91 | }, 92 | { 93 | 'folke/lazydev.nvim', 94 | ft = 'lua', 95 | }, 96 | { 97 | 'nvimdev/lspsaga.nvim', 98 | config = load_config('lang.lspsaga'), 99 | event = 'LspAttach', 100 | }, 101 | { 102 | 'williamboman/mason.nvim', 103 | config = load_config('lang.mason'), 104 | cmd = 'Mason', 105 | }, 106 | { 107 | 'nvimtools/none-ls.nvim', 108 | dependencies = { 'jay-babu/mason-null-ls.nvim' }, 109 | config = load_config('lang.null-ls'), 110 | event = { 'BufReadPost', 'BufNewFile' }, 111 | }, 112 | { 113 | 'saghen/blink.cmp', 114 | dependencies = { 115 | 'rafamadriz/friendly-snippets', 116 | 'Kaiser-Yang/blink-cmp-avante', 117 | }, 118 | version = '*', 119 | config = load_config('lang.blink'), 120 | opts_extend = { 'sources.default' }, 121 | event = { 'InsertEnter' }, 122 | }, 123 | 124 | -- AI 125 | { 126 | 'zbirenbaum/copilot.lua', 127 | dependencies = { 'giuxtaposition/blink-cmp-copilot' }, 128 | config = load_config('ai.copilot'), 129 | event = 'InsertEnter', 130 | }, 131 | { 132 | 'yetone/avante.nvim', 133 | version = false, 134 | config = load_config('ai.avante'), 135 | event = { 'BufReadPost', 'BufNewFile' }, 136 | build = 'make', 137 | -- build = "powershell -ExecutionPolicy Bypass -File Build.ps1 -BuildFromSource false" -- for windows 138 | dependencies = { 139 | 'MunifTanjim/nui.nvim', 140 | 'nvim-lua/plenary.nvim', 141 | 'ravitemer/mcphub.nvim', 142 | }, 143 | }, 144 | { 145 | 'ravitemer/mcphub.nvim', 146 | dependencies = { 'nvim-lua/plenary.nvim' }, 147 | cmd = 'MCPHub', 148 | -- build = 'npm install -g mcp-hub@latest', -- use this if you want to use the global mcp-hub 149 | build = 'bundled_build.lua', 150 | config = load_config('ai.mcphub'), 151 | }, 152 | 153 | -- Tools 154 | { 155 | 'echasnovski/mini.files', 156 | version = '*', 157 | config = load_config('tools.files'), 158 | event = { 'BufReadPost', 'BufNewFile' }, 159 | keys = { 160 | { 161 | 'ee', 162 | function() 163 | require('mini.files').open(util.get_file_path(), true) 164 | end, 165 | desc = 'Explorer', 166 | }, 167 | }, 168 | }, 169 | { 170 | 'michaelb/sniprun', 171 | build = 'bash ./install.sh', 172 | config = load_config('tools.sniprun'), 173 | cmd = 'SnipRun', 174 | }, 175 | { 176 | 'windwp/nvim-spectre', 177 | config = load_config('tools.spectre'), 178 | cmd = 'Spectre', 179 | }, 180 | { 181 | 'folke/flash.nvim', 182 | config = load_config('tools.flash'), 183 | keys = { 184 | { 185 | 's', 186 | mode = { 'n', 'x', 'o' }, 187 | function() 188 | require('flash').jump() 189 | end, 190 | desc = 'Flash', 191 | }, 192 | { 193 | 'S', 194 | mode = { 'n', 'x', 'o' }, 195 | function() 196 | require('flash').treesitter() 197 | end, 198 | desc = 'Flash Treesitter', 199 | }, 200 | }, 201 | }, 202 | { 203 | 'numToStr/Navigator.nvim', 204 | config = load_config('tools.navigator'), 205 | event = 'VeryLazy', 206 | }, 207 | { 208 | 'iamcco/markdown-preview.nvim', 209 | build = function() 210 | vim.fn['mkdp#util#install']() 211 | end, 212 | ft = 'markdown', 213 | cmd = { 'MarkdownPreviewToggle', 'MarkdownPreview' }, 214 | }, 215 | { 216 | 'uga-rosa/ccc.nvim', 217 | config = load_config('tools.ccc'), 218 | cmd = { 'CccHighlighterToggle', 'CccConvert', 'CccPick' }, 219 | }, 220 | { 221 | 'ruifm/gitlinker.nvim', 222 | config = load_config('tools.gitlinker'), 223 | keys = 'yg', 224 | }, 225 | { 226 | 'tpope/vim-fugitive', 227 | cmd = 'Git', 228 | }, 229 | 230 | -- Homegrown :) 231 | { 232 | '2kabhishek/pickme.nvim', 233 | cmd = 'PickMe', 234 | event = 'VeryLazy', 235 | dependencies = { 236 | 'folke/snacks.nvim', 237 | -- 'nvim-telescope/telescope.nvim', 238 | -- 'ibhagwan/fzf-lua', 239 | }, 240 | opts = { 241 | picker_provider = 'snacks', 242 | }, 243 | }, 244 | { 245 | '2kabhishek/utils.nvim', 246 | cmd = 'UtilsClearCache', 247 | }, 248 | { 249 | '2kabhishek/co-author.nvim', 250 | cmd = 'CoAuthor', 251 | }, 252 | { 253 | '2kabhishek/nerdy.nvim', 254 | cmd = 'Nerdy', 255 | }, 256 | { 257 | '2kabhishek/termim.nvim', 258 | cmd = { 'Fterm', 'FTerm', 'Sterm', 'STerm', 'Vterm', 'VTerm' }, 259 | }, 260 | { 261 | '2kabhishek/tdo.nvim', 262 | cmd = { 'Tdo', 'TdoEntry', 'TdoNote', 'TdoTodos', 'TdoToggle', 'TdoFind', 'TdoFiles' }, 263 | keys = { '[t', ']t' }, 264 | }, 265 | { 266 | '2kabhishek/octohub.nvim', 267 | cmd = { 268 | 'OctoRepos', 269 | 'OctoReposByCreated', 270 | 'OctoReposByForks', 271 | 'OctoReposByIssues', 272 | 'OctoReposByLanguages', 273 | 'OctoReposByNames', 274 | 'OctoReposByPushed', 275 | 'OctoReposBySize', 276 | 'OctoReposByStars', 277 | 'OctoReposByUpdated', 278 | 'OctoReposTypeArchived', 279 | 'OctoReposTypeForked', 280 | 'OctoReposTypePrivate', 281 | 'OctoReposTypeStarred', 282 | 'OctoReposTypeTemplate', 283 | 'OctoRepo', 284 | 'OctoStats', 285 | 'OctoActivityStats', 286 | 'OctoContributionStats', 287 | 'OctoRepoStats', 288 | 'OctoProfile', 289 | 'OctoRepoWeb', 290 | }, 291 | keys = { 292 | 'goa', 293 | 'goA', 294 | 'gob', 295 | 'goc', 296 | 'gof', 297 | 'goF', 298 | 'gog', 299 | 'goi', 300 | 'gol', 301 | 'goo', 302 | 'gop', 303 | 'goP', 304 | 'gor', 305 | 'gos', 306 | 'goS', 307 | 'got', 308 | 'goT', 309 | 'gou', 310 | 'goU', 311 | 'gow', 312 | }, 313 | dependencies = { 314 | '2kabhishek/utils.nvim', 315 | }, 316 | config = load_config('tools.octohub'), 317 | }, 318 | { 319 | '2kabhishek/exercism.nvim', 320 | cmd = { 321 | 'ExercismLanguages', 322 | 'ExercismList', 323 | 'ExercismSubmit', 324 | 'ExercismTest', 325 | }, 326 | keys = { 327 | 'exa', 328 | 'exl', 329 | 'exs', 330 | 'ext', 331 | }, 332 | dependencies = { 333 | '2kabhishek/utils.nvim', 334 | '2kabhishek/termim.nvim', 335 | }, 336 | config = load_config('tools.exercism'), 337 | -- opts = {}, 338 | -- dir = '~/Projects/2KAbhishek/exercism.nvim/', 339 | }, 340 | 341 | -- Optional 342 | { 343 | 'm4xshen/hardtime.nvim', 344 | dependencies = { 'MunifTanjim/nui.nvim', 'nvim-lua/plenary.nvim' }, 345 | cmd = 'Hardtime', 346 | enabled = util.get_user_config('enable_trainer', false), 347 | }, 348 | { 349 | 'kndndrj/nvim-dbee', 350 | dependencies = { 'MunifTanjim/nui.nvim' }, 351 | build = function() 352 | -- "curl", "wget", "bitsadmin", "go" 353 | require('dbee').install('curl') 354 | end, 355 | config = load_config('tools.dbee'), 356 | cmd = 'DBToggle', 357 | enabled = util.get_user_config('enable_db_explorer', false), 358 | }, 359 | { 360 | 'mfussenegger/nvim-dap', 361 | dependencies = { 'rcarriga/nvim-dap-ui' }, 362 | config = load_config('tools.dap'), 363 | cmd = { 'DapUIToggle', 'DapToggleRepl', 'DapToggleBreakpoint' }, 364 | enabled = util.get_user_config('enable_debugger', false), 365 | }, 366 | { 367 | 'nvim-neotest/neotest', 368 | dependencies = { 369 | 'nvim-neotest/nvim-nio', 370 | 'olimorris/neotest-rspec', 371 | 'nvim-neotest/neotest-jest', 372 | 'nvim-neotest/neotest-python', 373 | }, 374 | config = load_config('tools.neotest'), 375 | cmd = 'Neotest', 376 | enabled = util.get_user_config('enable_test_runner', false), 377 | }, 378 | } 379 | 380 | local treesitter_parsers = { 381 | 'bash', 382 | 'css', 383 | 'dart', 384 | 'elixir', 385 | 'gitcommit', 386 | 'go', 387 | 'html', 388 | 'java', 389 | 'javascript', 390 | 'json', 391 | 'lua', 392 | 'markdown', 393 | 'markdown_inline', -- markdown code blocks 394 | 'python', 395 | 'ruby', 396 | 'rust', 397 | 'typescript', 398 | 'vim', 399 | 'vimdoc', 400 | 'yaml', 401 | } 402 | 403 | local null_ls_sources = { 404 | 'shellcheck', 405 | } 406 | 407 | local lsp_servers = { 408 | 'bashls', 409 | 'jsonls', 410 | 'typos_lsp', 411 | 'vimls', 412 | } 413 | 414 | if util.is_present('npm') then 415 | table.insert(lsp_servers, 'eslint') 416 | table.insert(lsp_servers, 'ts_ls') 417 | end 418 | 419 | if util.is_present('gem') then 420 | table.insert(lsp_servers, 'solargraph') 421 | table.insert(lsp_servers, 'rubocop') 422 | end 423 | 424 | if util.is_present('go') then 425 | table.insert(lsp_servers, 'gopls') 426 | end 427 | 428 | if util.is_present('dart') then 429 | table.insert(lsp_servers, 'dartls') 430 | end 431 | 432 | if util.is_present('java') then 433 | table.insert(lsp_servers, 'jdtls') 434 | end 435 | 436 | if util.is_present('pip') then 437 | table.insert(lsp_servers, 'ruff') 438 | table.insert(lsp_servers, 'pylsp') 439 | end 440 | 441 | if util.is_present('mix') then 442 | table.insert(lsp_servers, 'elixirls') 443 | end 444 | 445 | if util.is_present('cargo') then 446 | table.insert(lsp_servers, 'rust_analyzer') 447 | end 448 | 449 | plugins = vim.tbl_extend('force', plugins, util.get_user_config('user_plugins', {})) 450 | lsp_servers = vim.tbl_extend('force', lsp_servers, util.get_user_config('user_lsp_servers', {})) 451 | null_ls_sources = vim.tbl_extend('force', null_ls_sources, util.get_user_config('user_null_ls_sources', {})) 452 | treesitter_parsers = vim.tbl_extend('force', treesitter_parsers, util.get_user_config('user_tresitter_parsers', {})) 453 | 454 | return { 455 | plugins = plugins, 456 | lsp_servers = lsp_servers, 457 | null_ls_sources = null_ls_sources, 458 | ts_parsers = treesitter_parsers, 459 | } 460 | -------------------------------------------------------------------------------- /lua/plugins/lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "Navigator.nvim": { "branch": "master", "commit": "91d86506ac2a039504d5205d32a1d4bc7aa57072" }, 3 | "avante.nvim": { "branch": "main", "commit": "d4672b7e1ee8bf94df5e1d3482e81418187f42aa" }, 4 | "blink-cmp-avante": { "branch": "master", "commit": "ddefb8de3cb1286ab39e0ccec0f32a45d03391f2" }, 5 | "blink-cmp-copilot": { "branch": "main", "commit": "439cff78780c033aa23cf061d7315314b347e3c1" }, 6 | "blink.cmp": { "branch": "main", "commit": "54cbaac2064fe6198ec55b636b53cc8c9791ead3" }, 7 | "ccc.nvim": { "branch": "main", "commit": "9d1a256e006decc574789dfc7d628ca11644d4c2" }, 8 | "copilot.lua": { "branch": "master", "commit": "2fe34db04570f6c47db0b752ca421a49b7357c03" }, 9 | "flash.nvim": { "branch": "main", "commit": "3c942666f115e2811e959eabbdd361a025db8b63" }, 10 | "friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" }, 11 | "gitlinker.nvim": { "branch": "master", "commit": "cc59f732f3d043b626c8702cb725c82e54d35c25" }, 12 | "gitsigns.nvim": { "branch": "main", "commit": "e399f9748d7cfd8859747c8d6c4e9c8b4d50a1bd" }, 13 | "hardtime.nvim": { "branch": "main", "commit": "5d9adcbe2f12741de79e435c8b85dca69a3b22e4" }, 14 | "lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" }, 15 | "lazydev.nvim": { "branch": "main", "commit": "2367a6c0a01eb9edb0464731cc0fb61ed9ab9d2c" }, 16 | "lspsaga.nvim": { "branch": "main", "commit": "920b1253e1a26732e53fac78412f6da7f674671d" }, 17 | "lualine.nvim": { "branch": "master", "commit": "15884cee63a8c205334ab13ab1c891cd4d27101a" }, 18 | "markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" }, 19 | "mason-lspconfig.nvim": { "branch": "main", "commit": "d39a75bbce4b8aad5d627191ea915179c77c100f" }, 20 | "mason-null-ls.nvim": { "branch": "main", "commit": "de19726de7260c68d94691afb057fa73d3cc53e7" }, 21 | "mason.nvim": { "branch": "main", "commit": "7c7318e8bae7e3536ef6b9e86b9e38e74f2e125e" }, 22 | "mcphub.nvim": { "branch": "main", "commit": "b254c452b921a8891d2fb7a2864e798f46fbed77" }, 23 | "mini.ai": { "branch": "main", "commit": "ebb04799794a7f94628153991e6334c3304961b8" }, 24 | "mini.bracketed": { "branch": "main", "commit": "079b8375e40ebf3f8af319ad835263ff390c3965" }, 25 | "mini.files": { "branch": "main", "commit": "01001e0cfc1e79f581d055ae3f70fbac96a2f378" }, 26 | "mini.pairs": { "branch": "main", "commit": "69864a2efb36c030877421634487fd90db1e4298" }, 27 | "mini.surround": { "branch": "main", "commit": "aa5e245829dd12d8ff0c96ef11da28681d6049aa" }, 28 | "neotest": { "branch": "master", "commit": "d66cf4e05a116957f0d3a7755a24291c7d1e1f72" }, 29 | "none-ls.nvim": { "branch": "main", "commit": "90e4a27ccaa25979a6b732b9f06dfa43b54957b7" }, 30 | "nui.nvim": { "branch": "main", "commit": "f535005e6ad1016383f24e39559833759453564e" }, 31 | "nvim-dap": { "branch": "master", "commit": "99807078c5089ed30e0547aa4b52c5867933f426" }, 32 | "nvim-lspconfig": { "branch": "master", "commit": "ac1dfbe3b60e5e23a2cff90e3bd6a3bc88031a57" }, 33 | "nvim-spectre": { "branch": "master", "commit": "72f56f7585903cd7bf92c665351aa585e150af0f" }, 34 | "nvim-spider": { "branch": "main", "commit": "9228ef94ca4e754ec90bcdeb8a5f552fa15ba8dc" }, 35 | "nvim-treesitter": { "branch": "master", "commit": "066fd6505377e3fd4aa219e61ce94c2b8bdb0b79" }, 36 | "nvim-treesitter-refactor": { "branch": "master", "commit": "d8b74fa87afc6a1e97b18da23e762efb032dc270" }, 37 | "nvim-treesitter-textobjects": { "branch": "master", "commit": "b0debd5c424969b4baeabdc8f54db3036c691732" }, 38 | "nvim-treesitter-textsubjects": { "branch": "master", "commit": "abcbb0e537c9c24800b03b9ca33bee5806604629" }, 39 | "nvim-web-devicons": { "branch": "master", "commit": "f1420728f59843eb2ef084406b3d0201a0a0932d" }, 40 | "onedark.nvim": { "branch": "master", "commit": "11de4da47f3e69cb70c3ae9816bd8af166cbe121" }, 41 | "plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" }, 42 | "snacks.nvim": { "branch": "main", "commit": "bc0630e43be5699bb94dadc302c0d21615421d93" }, 43 | "sniprun": { "branch": "master", "commit": "46f5a08df8b7b798d8c37d2b249af6b9ea8e75a3" }, 44 | "vim-fugitive": { "branch": "master", "commit": "4a745ea72fa93bb15dd077109afbb3d1809383f2" }, 45 | "which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" } 46 | } 47 | -------------------------------------------------------------------------------- /lua/plugins/tools/ccc.lua: -------------------------------------------------------------------------------- 1 | vim.opt.termguicolors = true 2 | 3 | local ccc = require('ccc') 4 | 5 | ccc.setup({ 6 | highlighter = { 7 | auto_enable = true, 8 | lsp = true, 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /lua/plugins/tools/dap.lua: -------------------------------------------------------------------------------- 1 | local dap = require('dap') 2 | local dapui = require('dapui') 3 | local icons = require('lib.icons') 4 | 5 | dapui.setup({ 6 | icons = { expanded = icons.ui.ArrowClosed, collapsed = icons.ui.ArrowOpen }, 7 | mappings = { 8 | expand = { '', '<2-LeftMouse>' }, 9 | open = 'o', 10 | remove = 'd', 11 | edit = 'e', 12 | repl = 'r', 13 | toggle = 't', 14 | }, 15 | expand_lines = vim.fn.has('nvim-0.7'), 16 | layouts = { 17 | { 18 | elements = { 19 | { id = 'scopes', size = 0.25 }, 20 | 'breakpoints', 21 | 'stacks', 22 | 'watches', 23 | }, 24 | size = 40, 25 | position = 'right', 26 | }, 27 | { 28 | elements = { 29 | 'repl', 30 | 'console', 31 | }, 32 | size = 0.25, 33 | position = 'bottom', 34 | }, 35 | }, 36 | floating = { 37 | max_height = nil, 38 | max_width = nil, 39 | border = 'rounded', 40 | mappings = { 41 | close = { 'q', '' }, 42 | }, 43 | }, 44 | windows = { indent = 1 }, 45 | render = { 46 | max_type_length = nil, 47 | }, 48 | }) 49 | 50 | vim.fn.sign_define('DapBreakpoint', { text = icons.ui.Bug, texthl = 'DiagnosticSignError', linehl = '', numhl = '' }) 51 | 52 | dap.listeners.after.event_initialized['dapui_config'] = function() 53 | dapui.open() 54 | end 55 | dap.listeners.before.event_terminated['dapui_config'] = function() 56 | dapui.close() 57 | end 58 | dap.listeners.before.event_exited['dapui_config'] = function() 59 | dapui.close() 60 | end 61 | 62 | dap.adapters.python = { 63 | type = 'executable', 64 | command = '/usr/bin/python', 65 | args = { '-m', 'debugpy.adapter' }, 66 | } 67 | 68 | dap.configurations.python = { 69 | { 70 | type = 'python', 71 | request = 'launch', 72 | name = 'Launch file', 73 | 74 | program = '${file}', 75 | pythonPath = function() 76 | local cwd = vim.fn.getcwd() 77 | if vim.fn.executable(cwd .. '/venv/bin/python') == 1 then 78 | return cwd .. '/venv/bin/python' 79 | elseif vim.fn.executable(cwd .. '/.venv/bin/python') == 1 then 80 | return cwd .. '/.venv/bin/python' 81 | else 82 | return '/usr/bin/python' 83 | end 84 | end, 85 | }, 86 | } 87 | 88 | dap.adapters.ruby = { 89 | type = 'executable', 90 | command = 'bundle', 91 | args = { 'exec', 'readapt', 'stdio' }, 92 | } 93 | 94 | dap.configurations.ruby = { 95 | { 96 | type = 'ruby', 97 | request = 'launch', 98 | name = 'Rails', 99 | program = 'bundle', 100 | programArgs = { 'exec', 'rails', 's' }, 101 | useBundler = true, 102 | }, 103 | } 104 | 105 | vim.api.nvim_create_user_command('DapUIToggle', function() 106 | require('dapui').toggle() 107 | end, {}) 108 | -------------------------------------------------------------------------------- /lua/plugins/tools/dbee.lua: -------------------------------------------------------------------------------- 1 | local dbee = require('dbee') 2 | 3 | dbee.setup({ 4 | sources = { 5 | require('dbee.sources').EnvSource:new('NVIM_DB'), 6 | -- require("dbee.sources").MemorySource:new({ 7 | -- { 8 | -- name = "dbname", 9 | -- type = "postgres", 10 | -- url = "postgres://pguser:pguser@localhost:5602/dbname?sslmode=disable" 11 | -- }, 12 | -- }), 13 | -- require("dbee.sources").FileSource:new(vim.fn.stdpath("cache") .. "/dbee/config.json"), 14 | }, 15 | }) 16 | 17 | vim.api.nvim_create_user_command('DBToggle', function() 18 | require('dbee').toggle() 19 | end, {}) 20 | -------------------------------------------------------------------------------- /lua/plugins/tools/exercism.lua: -------------------------------------------------------------------------------- 1 | local exercism = require('exercism') 2 | 3 | exercism.setup({ 4 | exercism_workspace = '~/Projects/2KAbhishek/exercism', 5 | add_default_keybindings = true, 6 | default_language = 'elixir', 7 | }) 8 | -------------------------------------------------------------------------------- /lua/plugins/tools/files.lua: -------------------------------------------------------------------------------- 1 | local files = require('mini.files') 2 | 3 | files.setup({ 4 | content = { 5 | filter = nil, 6 | prefix = nil, 7 | sort = nil, 8 | }, 9 | mappings = { 10 | close = 'q', 11 | go_in = 'L', 12 | go_in_plus = 'l', 13 | go_out = 'h', 14 | go_out_plus = 'H', 15 | mark_goto = "'", 16 | mark_set = 'm', 17 | reset = '', 18 | reveal_cwd = '@', 19 | show_help = 'g?', 20 | synchronize = '', 21 | trim_left = '<', 22 | trim_right = '>', 23 | }, 24 | options = { 25 | permanent_delete = true, 26 | use_as_default_explorer = true, 27 | }, 28 | windows = { 29 | max_number = math.huge, 30 | preview = false, 31 | width_focus = 30, 32 | width_nofocus = 20, 33 | width_preview = 80, 34 | }, 35 | }) 36 | 37 | vim.api.nvim_set_hl(0, 'MiniFilesBorder', { bg = 'none' }) 38 | vim.api.nvim_set_hl(0, 'MiniFilesNormal', { bg = 'none' }) 39 | vim.api.nvim_set_hl(0, 'MiniFilesTitle', { bg = 'none' }) 40 | -------------------------------------------------------------------------------- /lua/plugins/tools/flash.lua: -------------------------------------------------------------------------------- 1 | local flash = require('flash') 2 | local icons = require('lib.icons') 3 | 4 | flash.setup({ 5 | -- exact, fuzzy, regex, custom function 6 | mode = 'fuzzy', 7 | -- behave like `incsearch` 8 | incremental = true, 9 | 10 | jump = { 11 | -- save location in the jumplist 12 | jumplist = true, 13 | -- automatically jump when there is only one match 14 | autojump = true, 15 | }, 16 | label = { 17 | rainbow = { 18 | enabled = true, 19 | -- number between 1 and 9 20 | shade = 4, 21 | }, 22 | }, 23 | prompt = { 24 | enabled = true, 25 | prefix = { { icons.ui.Separator .. icons.ui.Rocket .. icons.ui.ChevronRight .. ' ', 'FlashPromptIcon' } }, 26 | win_config = { relative = 'editor', width = 1, height = 1, row = 1, col = 0, zindex = 1000 }, 27 | }, 28 | modes = { 29 | search = { 30 | enabled = true, 31 | }, 32 | char = { 33 | enabled = false, 34 | jump_labels = false, 35 | }, 36 | }, 37 | }) 38 | 39 | vim.api.nvim_create_user_command('FlashDiagnostics', function() 40 | require('flash').jump({ 41 | matcher = function(win) 42 | return vim.tbl_map(function(diag) 43 | return { 44 | pos = { diag.lnum + 1, diag.col }, 45 | end_pos = { diag.end_lnum + 1, diag.end_col - 1 }, 46 | } 47 | end, vim.diagnostic.get(vim.api.nvim_win_get_buf(win))) 48 | end, 49 | action = function(match, state) 50 | vim.api.nvim_win_call(match.win, function() 51 | vim.api.nvim_win_set_cursor(match.win, match.pos) 52 | vim.diagnostic.open_float() 53 | end) 54 | state:restore() 55 | end, 56 | }) 57 | end, {}) 58 | -------------------------------------------------------------------------------- /lua/plugins/tools/gitlinker.lua: -------------------------------------------------------------------------------- 1 | local gitlinker = require('gitlinker') 2 | 3 | gitlinker.setup({ 4 | opts = { 5 | remote = nil, 6 | add_current_line_on_normal_mode = true, 7 | action_callback = require('gitlinker.actions').copy_to_clipboard, 8 | print_url = true, 9 | }, 10 | callbacks = { 11 | ['github.com'] = require('gitlinker.hosts').get_github_type_url, 12 | ['gitlab.com'] = require('gitlinker.hosts').get_gitlab_type_url, 13 | ['try.gitea.io'] = require('gitlinker.hosts').get_gitea_type_url, 14 | ['codeberg.org'] = require('gitlinker.hosts').get_gitea_type_url, 15 | ['bitbucket.org'] = require('gitlinker.hosts').get_bitbucket_type_url, 16 | ['try.gogs.io'] = require('gitlinker.hosts').get_gogs_type_url, 17 | ['git.sr.ht'] = require('gitlinker.hosts').get_srht_type_url, 18 | ['git.launchpad.net'] = require('gitlinker.hosts').get_launchpad_type_url, 19 | ['repo.or.cz'] = require('gitlinker.hosts').get_repoorcz_type_url, 20 | ['git.kernel.org'] = require('gitlinker.hosts').get_cgit_type_url, 21 | ['git.savannah.gnu.org'] = require('gitlinker.hosts').get_cgit_type_url, 22 | }, 23 | mappings = 'yg', 24 | }) 25 | -------------------------------------------------------------------------------- /lua/plugins/tools/navigator.lua: -------------------------------------------------------------------------------- 1 | local navigator = require('Navigator') 2 | 3 | navigator.setup({ 4 | auto_save = 'current', 5 | disable_on_zoom = false, 6 | mux = 'auto', 7 | }) 8 | 9 | -------------------------------------------------------------------------------- /lua/plugins/tools/neotest.lua: -------------------------------------------------------------------------------- 1 | local neotest = require('neotest') 2 | 3 | neotest.setup({ 4 | adapters = { 5 | require('neotest-rspec')({ 6 | rspec_cmd = function() 7 | return vim.tbl_flatten({ 8 | 'bundle', 9 | 'exec', 10 | 'rspec', 11 | }) 12 | end, 13 | }), 14 | require('neotest-jest')({ 15 | jestCommand = 'npx jest --', 16 | jestConfigFile = 'jest.config.js', 17 | }), 18 | require('neotest-python'), 19 | }, 20 | }) 21 | -------------------------------------------------------------------------------- /lua/plugins/tools/octohub.lua: -------------------------------------------------------------------------------- 1 | local octohub = require('octohub') 2 | 3 | octohub.setup({ 4 | per_user_dir = true, 5 | projects_dir = '~/Projects/', 6 | contribution_icons = { '', '', '', '', '', '', '' }, 7 | sort_repos_by = '', 8 | repo_type = '', 9 | max_contributions = 50, 10 | top_lang_count = 5, 11 | event_count = 5, 12 | window_width = 90, 13 | window_height = 60, 14 | show_recent_activity = true, 15 | show_contributions = true, 16 | show_repo_stats = true, 17 | add_default_keybindings = true, 18 | }) 19 | -------------------------------------------------------------------------------- /lua/plugins/tools/sniprun.lua: -------------------------------------------------------------------------------- 1 | local sniprun = require('sniprun') 2 | local sniprun_api = require('sniprun.api') 3 | 4 | sniprun.setup({ 5 | display = { 'Api' }, 6 | show_no_output = { 'Classic', 'TempFloatingWindow' }, 7 | 8 | display_options = { 9 | terminal_width = 45, 10 | notification_timeout = 5, 11 | }, 12 | 13 | inline_messages = 0, 14 | borders = 'single', 15 | }) 16 | 17 | local api_listener = function(d) 18 | if d.status == 'ok' then 19 | vim.notify('Output: \n' .. d.message, vim.log.levels.INFO) 20 | elseif d.status == 'error' then 21 | vim.notify('Error: \n' .. d.message, vim.log.levels.ERROR) 22 | else 23 | vim.notify('Sniprun: ' .. d.message, vim.log.levels.INFO) 24 | end 25 | end 26 | 27 | sniprun_api.register_listener(api_listener) 28 | -------------------------------------------------------------------------------- /lua/plugins/tools/spectre.lua: -------------------------------------------------------------------------------- 1 | local spectre = require('spectre') 2 | 3 | spectre.setup({ 4 | color_devicons = true, 5 | highlight = { 6 | ui = 'String', 7 | search = 'DiffChange', 8 | replace = 'DiffDelete', 9 | }, 10 | mapping = { 11 | ['toggle_line'] = { 12 | map = 't', 13 | cmd = ":lua require('spectre').toggle_line()", 14 | desc = 'toggle current item', 15 | }, 16 | ['enter_file'] = { 17 | map = '', 18 | cmd = ":lua require('spectre.actions').select_entry()", 19 | desc = 'goto current file', 20 | }, 21 | ['send_to_qf'] = { 22 | map = 'Q', 23 | cmd = ":lua require('spectre.actions').send_to_qf()", 24 | desc = 'send all item to quickfix', 25 | }, 26 | ['replace_cmd'] = { 27 | map = 'c', 28 | cmd = ":lua require('spectre.actions').replace_cmd()", 29 | desc = 'input replace vim command', 30 | }, 31 | ['show_option_menu'] = { 32 | map = 'o', 33 | cmd = ":lua require('spectre').show_options()", 34 | desc = 'show option', 35 | }, 36 | ['run_replace'] = { 37 | map = 'R', 38 | cmd = ":lua require('spectre.actions').run_replace()", 39 | desc = 'replace all', 40 | }, 41 | ['change_view_mode'] = { 42 | map = 'm', 43 | cmd = ":lua require('spectre').change_view()", 44 | desc = 'change result view mode', 45 | }, 46 | ['toggle_ignore_case'] = { 47 | map = 'I', 48 | cmd = ":lua require('spectre').change_options('ignore-case')", 49 | desc = 'toggle ignore case', 50 | }, 51 | ['toggle_ignore_hidden'] = { 52 | map = 'H', 53 | cmd = ":lua require('spectre').change_options('hidden')", 54 | desc = 'toggle search hidden', 55 | }, 56 | }, 57 | find_engine = { 58 | ['rg'] = { 59 | cmd = 'rg', 60 | args = { 61 | '--color=never', 62 | '--no-heading', 63 | '--with-filename', 64 | '--line-number', 65 | '--column', 66 | }, 67 | options = { 68 | ['ignore-case'] = { 69 | value = '--ignore-case', 70 | icon = '[I]', 71 | desc = 'ignore case', 72 | }, 73 | ['hidden'] = { 74 | value = '--hidden', 75 | desc = 'hidden file', 76 | icon = '[H]', 77 | }, 78 | }, 79 | }, 80 | ['ag'] = { 81 | cmd = 'ag', 82 | args = { 83 | '--vimgrep', 84 | '-s', 85 | }, 86 | options = { 87 | ['ignore-case'] = { 88 | value = '-i', 89 | icon = '[I]', 90 | desc = 'ignore case', 91 | }, 92 | ['hidden'] = { 93 | value = '--hidden', 94 | desc = 'hidden file', 95 | icon = '[H]', 96 | }, 97 | }, 98 | }, 99 | }, 100 | replace_engine = { 101 | ['sed'] = { 102 | cmd = 'sed', 103 | args = nil, 104 | }, 105 | options = { 106 | ['ignore-case'] = { 107 | value = '--ignore-case', 108 | icon = '[I]', 109 | desc = 'ignore case', 110 | }, 111 | }, 112 | }, 113 | default = { 114 | find = { 115 | cmd = 'rg', 116 | options = { 'ignore-case' }, 117 | }, 118 | replace = { 119 | cmd = 'sed', 120 | }, 121 | }, 122 | replace_vim_cmd = 'cdo', 123 | is_open_target_win = true, 124 | is_insert_mode = true, 125 | }) 126 | -------------------------------------------------------------------------------- /lua/plugins/ui/gitsigns.lua: -------------------------------------------------------------------------------- 1 | local gitsigns = require('gitsigns') 2 | local icons = require('lib.icons') 3 | 4 | gitsigns.setup({ 5 | signs = { 6 | add = { text = icons.ui.SeparatorLight }, 7 | change = { text = icons.ui.SeparatorLight }, 8 | delete = { text = icons.ui.SeparatorLight }, 9 | topdelete = { text = icons.ui.Topline }, 10 | changedelete = { text = icons.ui.SeparatorLight }, 11 | untracked = { text = icons.ui.SeparatorDashed }, 12 | }, 13 | signcolumn = true, 14 | numhl = false, 15 | linehl = false, 16 | word_diff = false, 17 | watch_gitdir = { interval = 1000, follow_files = true }, 18 | attach_to_untracked = true, 19 | current_line_blame = false, 20 | current_line_blame_opts = { 21 | virt_text = true, 22 | virt_text_pos = 'eol', 23 | delay = 0, 24 | ignore_whitespace = false, 25 | }, 26 | current_line_blame_formatter = ', - ', 27 | sign_priority = 6, 28 | update_debounce = 100, 29 | status_formatter = nil, 30 | max_file_length = 40000, 31 | preview_config = { border = 'rounded', style = 'minimal', relative = 'cursor', row = 0, col = 1 }, 32 | on_attach = function(bufnr) 33 | local gs = package.loaded.gitsigns 34 | 35 | local function map(mode, l, r, opts) 36 | opts = opts or {} 37 | opts.buffer = bufnr 38 | vim.keymap.set(mode, l, r, opts) 39 | end 40 | 41 | map('n', ']e', function() 42 | if vim.wo.diff then 43 | return ']e' 44 | end 45 | vim.schedule(function() 46 | gs.next_hunk() 47 | end) 48 | return '' 49 | end, { expr = true, desc = 'Next Change' }) 50 | 51 | map('n', '[e', function() 52 | if vim.wo.diff then 53 | return '[e' 54 | end 55 | vim.schedule(function() 56 | gs.prev_hunk() 57 | end) 58 | return '' 59 | end, { expr = true, desc = 'Prev Change' }) 60 | 61 | map({ 'o', 'x' }, 'ih', ':Gitsigns select_hunk') 62 | end, 63 | }) 64 | -------------------------------------------------------------------------------- /lua/plugins/ui/lualine.lua: -------------------------------------------------------------------------------- 1 | local lualine = require('lualine') 2 | local icons = require('lib.icons') 3 | 4 | local colors = { 5 | bg = '#000000', 6 | fg = '#bbc2cf', 7 | yellow = '#ECBE7B', 8 | cyan = '#008080', 9 | darkblue = '#081633', 10 | green = '#98be65', 11 | orange = '#FF8800', 12 | violet = '#a9a1e1', 13 | magenta = '#c678dd', 14 | blue = '#51afef', 15 | red = '#ec5f67', 16 | } 17 | 18 | local mode_color = { 19 | n = colors.green, 20 | i = colors.blue, 21 | v = colors.magenta, 22 | [''] = colors.magenta, 23 | V = colors.magenta, 24 | c = colors.yellow, 25 | t = colors.red, 26 | R = colors.orange, 27 | Rv = colors.orange, 28 | no = colors.fg, 29 | s = colors.violet, 30 | S = colors.violet, 31 | [''] = colors.violet, 32 | ic = colors.yellow, 33 | cv = colors.red, 34 | ce = colors.red, 35 | r = colors.cyan, 36 | rm = colors.cyan, 37 | ['r?'] = colors.cyan, 38 | ['!'] = colors.red, 39 | } 40 | 41 | local conditions = { 42 | buffer_not_empty = function() 43 | return vim.fn.empty(vim.fn.expand('%:t')) ~= 1 44 | end, 45 | buffer_is_file = function() 46 | return vim.bo.buftype == '' 47 | end, 48 | buffer_not_scratch = function() 49 | return string.find(vim.fn.bufname(), 'SCRATCH') == nil 50 | end, 51 | hide_in_width = function() 52 | return vim.fn.winwidth(0) > 80 53 | end, 54 | check_git_workspace = function() 55 | local filepath = vim.fn.expand('%:p:h') 56 | local gitdir = vim.fn.finddir('.git', filepath .. ';') 57 | return gitdir and #gitdir > 0 and #gitdir < #filepath 58 | end, 59 | } 60 | 61 | local searchcount = { 'searchcount', color = { fg = colors.fg, gui = 'bold' } } 62 | local selectioncount = { 'selectioncount', color = { fg = colors.fg, gui = 'bold' } } 63 | local progress = { 'progress', color = { fg = colors.fg, gui = 'bold' } } 64 | local filetype = { 'filetype', color = { fg = colors.blue, gui = 'bold' } } 65 | local filesize = { 'filesize', color = { fg = colors.fg, gui = 'bold' }, cond = conditions.buffer_not_empty } 66 | local fileformat = { 'fileformat', icons_enabled = true, color = { fg = colors.white, gui = 'bold' } } 67 | 68 | local filename = { 69 | 'filename', 70 | cond = conditions.buffer_not_empty and conditions.buffer_is_file and conditions.buffer_not_scratch, 71 | color = { fg = colors.magenta, gui = 'bold' }, 72 | } 73 | 74 | local buffers = { 75 | 'buffers', 76 | mode = 2, 77 | cond = conditions.buffer_not_scratch, 78 | filetype_names = { 79 | NvimTree = icons.documents.OpenFolder .. 'Files', 80 | TelescopePrompt = icons.ui.Telescope .. 'Telescope', 81 | Avante = icons.ui.Copilot .. 'Avante', 82 | AvanteInput = icons.ui.Pencil .. 'Avante', 83 | AvanteSelectedFiles = icons.documents.File .. 'Avante', 84 | dashboard = icons.ui.Dashboard .. 'Dashboard', 85 | lazy = icons.ui.Sleep .. 'Lazy', 86 | mason = icons.ui.Package .. 'Mason', 87 | minifiles = icons.documents.OpenFolder .. 'Files', 88 | snacks_picker_input = icons.ui.Telescope .. 'Picker', 89 | spectre_panel = icons.ui.Search .. 'Spectre', 90 | }, 91 | use_mode_colors = true, 92 | } 93 | 94 | local branch = { 95 | 'branch', 96 | icon = icons.git.Branch, 97 | fmt = function(str) 98 | return str:sub(1, 32) 99 | end, 100 | color = { fg = colors.green, gui = 'bold' }, 101 | } 102 | 103 | local diff_icons = { 104 | 'diff', 105 | symbols = { added = icons.git.AddAlt, modified = icons.git.DiffAlt, removed = icons.git.RemoveAlt }, 106 | diff_color = { 107 | added = { fg = colors.green }, 108 | modified = { fg = colors.orange }, 109 | removed = { fg = colors.red }, 110 | }, 111 | cond = conditions.hide_in_width, 112 | } 113 | 114 | local diagnostics = { 115 | 'diagnostics', 116 | sources = { 'nvim_lsp', 'nvim_diagnostic', 'nvim_workspace_diagnostic' }, 117 | symbols = { 118 | error = icons.diagnostics.Error, 119 | warn = icons.diagnostics.Warning, 120 | info = icons.diagnostics.Information, 121 | hint = icons.diagnostics.Hint, 122 | }, 123 | diagnostics_color = { 124 | color_error = { fg = colors.red }, 125 | color_warn = { fg = colors.yellow }, 126 | color_info = { fg = colors.blue }, 127 | color_hint = { fg = colors.yellow }, 128 | }, 129 | } 130 | 131 | local lsp = { 132 | function() 133 | local msg = 'No LSP' 134 | local buf_ft = vim.api.nvim_get_option_value('filetype', { buf = 0 }) 135 | local clients = vim.lsp.get_clients() 136 | if next(clients) == nil then 137 | return msg 138 | end 139 | for _, client in ipairs(clients) do 140 | local filetypes = client.config and client.config.filetypes or nil 141 | if filetypes and vim.fn.index(filetypes, buf_ft) ~= -1 then 142 | return client.name 143 | end 144 | end 145 | return msg 146 | end, 147 | icon = icons.ui.Gear, 148 | color = { fg = colors.fg, gui = 'bold' }, 149 | } 150 | 151 | local encoding = { 152 | 'o:encoding', 153 | fmt = string.upper, 154 | cond = conditions.hide_in_width, 155 | color = { fg = colors.green, gui = 'bold' }, 156 | } 157 | 158 | local function mode(icon) 159 | icon = icon or icons.ui.Neovim 160 | return { 161 | function() 162 | return icon 163 | end, 164 | color = function() 165 | return { fg = mode_color[vim.fn.mode()] } 166 | end, 167 | padding = { left = 1, right = 0 }, 168 | } 169 | end 170 | 171 | local custom_onedark = require('lualine.themes.onedark') 172 | custom_onedark.normal.c.bg = colors.bg 173 | 174 | lualine.setup({ 175 | options = { 176 | component_separators = '', 177 | -- section_separators = '', 178 | theme = custom_onedark, 179 | disabled_filetypes = { 180 | 'dashboard', 181 | }, 182 | }, 183 | -- extensions = { 'quickfix', 'man', 'mason', 'lazy', 'toggleterm', 'nvim-tree' }, 184 | tabline = { 185 | lualine_a = {}, 186 | lualine_b = { mode(), buffers }, 187 | lualine_c = {}, 188 | lualine_x = { diff_icons, branch }, 189 | lualine_y = { searchcount, selectioncount }, 190 | lualine_z = {}, 191 | }, 192 | sections = { 193 | lualine_a = {}, 194 | lualine_b = {}, 195 | lualine_c = { mode(icons.ui.Heart), 'location', progress, filename }, 196 | lualine_x = { diagnostics, lsp, filetype, filesize, fileformat, encoding }, 197 | lualine_y = {}, 198 | lualine_z = {}, 199 | }, 200 | }) 201 | -------------------------------------------------------------------------------- /lua/plugins/ui/markit.lua: -------------------------------------------------------------------------------- 1 | local markit = require('markit') 2 | local icons = require('lib.icons') 3 | 4 | markit.setup({ 5 | default_mappings = true, 6 | builtin_marks = { '.', '<', '>', '^' }, 7 | cyclic = true, 8 | force_write_shada = false, 9 | sign_priority = { lower = 10, upper = 15, builtin = 8, bookmark = 20 }, 10 | excluded_filetypes = {}, 11 | excluded_buftypes = { 'nofile' }, 12 | -- supports up to 10 bookmark groups 13 | bookmark_1 = { 14 | sign = icons.ui.Flag, 15 | virt_text = 'flag', 16 | annotate = false, 17 | }, 18 | bookmark_2 = { 19 | sign = icons.ui.Eye, 20 | virt_text = 'watch', 21 | annotate = false, 22 | }, 23 | bookmark_3 = { 24 | sign = icons.ui.Star, 25 | virt_text = 'star', 26 | annotate = false, 27 | }, 28 | bookmark_4 = { 29 | sign = icons.ui.Bug, 30 | virt_text = 'bug', 31 | annotate = false, 32 | }, 33 | mappings = { 34 | set = 'M', 35 | toggle_mark = 'm', 36 | }, 37 | }) 38 | -------------------------------------------------------------------------------- /lua/plugins/ui/onedark.lua: -------------------------------------------------------------------------------- 1 | local onedark = require('onedark') 2 | 3 | onedark.setup({ 4 | style = 'deep', 5 | transparent = true, 6 | term_colors = false, 7 | ending_tildes = false, 8 | cmp_itemkind_reverse = false, 9 | 10 | toggle_style_key = 'ot', 11 | toggle_style_list = { 'dark', 'darker', 'cool', 'warm', 'warmer', 'deep', 'light' }, 12 | 13 | -- Options are italic, bold, underline, none and combos 'italic,bold' 14 | code_style = { 15 | comments = 'italic', 16 | keywords = 'none', 17 | functions = 'none', 18 | strings = 'none', 19 | variables = 'none', 20 | }, 21 | 22 | lualine = { transparent = true }, 23 | diagnostics = { darker = true, undercurl = true, background = false }, 24 | }) 25 | onedark.load() 26 | -------------------------------------------------------------------------------- /lua/plugins/ui/snacks.lua: -------------------------------------------------------------------------------- 1 | local Snacks = require('snacks') 2 | local icons = require('lib.icons') 3 | 4 | local function files_layout(preview_width, height, width) 5 | preview_width = preview_width or 0.6 6 | height = height or 0.8 7 | width = width or 0.9 8 | return { 9 | layout = { 10 | box = 'horizontal', 11 | width = width, 12 | min_width = 120, 13 | height = height, 14 | { 15 | box = 'vertical', 16 | border = 'rounded', 17 | title = '{title} {live} {flags}', 18 | { win = 'input', height = 1, border = 'bottom' }, 19 | { win = 'list', border = 'none' }, 20 | }, 21 | { win = 'preview', title = '{preview}', border = 'rounded', width = preview_width }, 22 | }, 23 | } 24 | end 25 | 26 | local function palette_layout(height, width) 27 | height = height or 0.4 28 | width = width or 0.6 29 | return { 30 | preview = false, 31 | layout = { 32 | backdrop = false, 33 | row = 1, 34 | width = width, 35 | min_width = 80, 36 | height = height, 37 | border = 'rounded', 38 | box = 'vertical', 39 | { 40 | win = 'input', 41 | height = 1, 42 | border = 'rounded', 43 | title = '{title} {live} {flags}', 44 | title_pos = 'center', 45 | }, 46 | { win = 'list', border = 'hpad' }, 47 | { win = 'preview', title = '{preview}', border = 'rounded' }, 48 | }, 49 | } 50 | end 51 | 52 | Snacks.setup({ 53 | animate = { 54 | enabled = true, 55 | duration = 20, -- ms per step 56 | easing = 'linear', 57 | fps = 60, 58 | }, 59 | bigfile = { 60 | enabled = true, 61 | notify = true, 62 | size = 100 * 1024, -- 100 KB 63 | }, 64 | bufdelete = { enabled = true }, 65 | dashboard = { 66 | enabled = true, 67 | sections = { 68 | { section = 'header' }, 69 | { 70 | icon = icons.ui.Keyboard, 71 | title = 'Keymaps', 72 | section = 'keys', 73 | indent = 2, 74 | padding = 1, 75 | }, 76 | { 77 | icon = icons.documents.File, 78 | title = 'Recent Files', 79 | section = 'recent_files', 80 | indent = 2, 81 | padding = 1, 82 | }, 83 | { 84 | icon = icons.documents.OpenFolder, 85 | title = 'Projects', 86 | section = 'projects', 87 | indent = 2, 88 | padding = 1, 89 | }, 90 | { section = 'startup' }, 91 | }, 92 | }, 93 | debug = { enabled = true }, 94 | dim = { 95 | enabled = true, 96 | scope = { 97 | min_size = 5, 98 | max_size = 20, 99 | siblings = true, 100 | }, 101 | }, 102 | explorer = { enabled = false }, 103 | git = { enabled = true }, 104 | gitbrowse = { enabled = true }, 105 | image = { enabled = true }, 106 | indent = { 107 | enabled = true, 108 | priority = 1, 109 | char = icons.ui.SeparatorLight, 110 | only_scope = false, 111 | only_current = false, 112 | hl = { 113 | 'SnacksIndent1', 114 | 'SnacksIndent2', 115 | 'SnacksIndent3', 116 | 'SnacksIndent4', 117 | 'SnacksIndent5', 118 | 'SnacksIndent6', 119 | 'SnacksIndent7', 120 | 'SnacksIndent8', 121 | }, 122 | }, 123 | input = { 124 | enabled = true, 125 | icon = icons.ui.Edit, 126 | icon_hl = 'SnacksInputIcon', 127 | icon_pos = 'left', 128 | prompt_pos = 'title', 129 | win = { style = 'input' }, 130 | expand = true, 131 | }, 132 | layout = { enabled = true }, 133 | lazygit = { enabled = true }, 134 | notifier = { 135 | enabled = true, 136 | timeout = 2000, 137 | width = { min = 40, max = 0.4 }, 138 | height = { min = 1, max = 0.6 }, 139 | margin = { top = 0, right = 1, bottom = 0 }, 140 | padding = true, 141 | sort = { 'level', 'added' }, 142 | level = vim.log.levels.TRACE, 143 | icons = { 144 | debug = icons.ui.Bug, 145 | error = icons.diagnostics.Error, 146 | info = icons.diagnostics.Information, 147 | trace = icons.ui.Bookmark, 148 | warn = icons.diagnostics.Warning, 149 | }, 150 | style = 'compact', 151 | top_down = true, 152 | date_format = '%R', 153 | more_format = ' ↓ %d lines ', 154 | refresh = 50, 155 | }, 156 | notify = { enabled = true }, 157 | picker = { 158 | enabled = true, 159 | icon = icons.ui.Search, 160 | icon_hl = 'SnacksPickerIcon', 161 | icon_pos = 'left', 162 | prompt_pos = 'title', 163 | win = { style = 'picker' }, 164 | expand = true, 165 | sources = { 166 | -- layout options: dropdown, horizontal, vertical, vscode, ivy, ivy_split, telescope, top, left, right, bottom, sidebar 167 | buffers = { layout = files_layout() }, 168 | commands = { layout = palette_layout() }, 169 | command_history = { layout = palette_layout() }, 170 | files = { 171 | hidden = true, 172 | layout = files_layout(), 173 | }, 174 | icons = { 175 | icon_sources = { 'nerd_fonts', 'emoji' }, 176 | layout = palette_layout(), 177 | }, 178 | git_files = { layout = files_layout() }, 179 | git_branches = { layout = { preset = 'vertical' } }, 180 | git_status = { layout = files_layout() }, 181 | help = { layout = { preset = 'ivy_split' } }, 182 | man = { layout = { preset = 'ivy_split' } }, 183 | notifications = { layout = palette_layout() }, 184 | projects = { layout = files_layout(0.8) }, 185 | recent = { layout = files_layout() }, 186 | search_history = { layout = palette_layout() }, 187 | smart = { layout = files_layout() }, 188 | undo = { layout = { preset = 'ivy' } }, 189 | zoxide = { layout = files_layout(0.7) }, 190 | }, 191 | }, 192 | profiler = { enabled = true }, 193 | quickfile = { enabled = true }, 194 | rename = { enabled = true }, 195 | scope = { 196 | enabled = true, 197 | keys = { 198 | textobject = { 199 | ii = { 200 | min_size = 2, -- minimum size of the scope 201 | edge = false, -- inner scope 202 | cursor = false, 203 | treesitter = { blocks = { enabled = false } }, 204 | desc = 'inner scope', 205 | }, 206 | ai = { 207 | cursor = false, 208 | min_size = 2, -- minimum size of the scope 209 | treesitter = { blocks = { enabled = false } }, 210 | desc = 'full scope', 211 | }, 212 | }, 213 | jump = { 214 | ['[a'] = { 215 | min_size = 1, -- allow single line scopes 216 | bottom = false, 217 | cursor = false, 218 | edge = true, 219 | treesitter = { blocks = { enabled = false } }, 220 | desc = 'jump to top edge of scope', 221 | }, 222 | [']a'] = { 223 | min_size = 1, -- allow single line scopes 224 | bottom = true, 225 | cursor = false, 226 | edge = true, 227 | treesitter = { blocks = { enabled = false } }, 228 | desc = 'jump to bottom edge of scope', 229 | }, 230 | }, 231 | }, 232 | }, 233 | scratch = { 234 | enabled = true, 235 | name = 'SCRATCH', 236 | ft = function() 237 | if vim.bo.buftype == '' and vim.bo.filetype ~= '' then 238 | return vim.bo.filetype 239 | end 240 | return 'markdown' 241 | end, 242 | icon = nil, 243 | root = vim.fn.stdpath('data') .. '/scratch', 244 | autowrite = true, 245 | filekey = { 246 | cwd = true, 247 | branch = true, 248 | count = true, 249 | }, 250 | win = { 251 | width = 120, 252 | height = 40, 253 | bo = { buftype = '', buflisted = false, bufhidden = 'hide', swapfile = false }, 254 | minimal = false, 255 | noautocmd = false, 256 | zindex = 20, 257 | wo = { winhighlight = 'NormalFloat:Normal' }, 258 | border = 'rounded', 259 | title_pos = 'center', 260 | footer_pos = 'center', 261 | 262 | keys = { 263 | ['execute'] = { 264 | '', 265 | function(_) 266 | vim.cmd('%SnipRun') 267 | end, 268 | desc = 'Execute buffer', 269 | mode = { 'n', 'x' }, 270 | }, 271 | }, 272 | }, 273 | win_by_ft = { 274 | lua = { 275 | keys = { 276 | ['source'] = { 277 | 'cr', 278 | function(self) 279 | local name = 'scratch.' .. vim.fn.fnamemodify(vim.api.nvim_buf_get_name(self.buf), ':e') 280 | Snacks.debug.run({ buf = self.buf, name = name }) 281 | end, 282 | desc = 'Source buffer', 283 | mode = { 'n', 'x' }, 284 | }, 285 | }, 286 | }, 287 | }, 288 | }, 289 | scroll = { enabled = false }, 290 | statuscolumn = { 291 | enabled = true, 292 | left = { 'mark', 'sign' }, 293 | right = { 'fold', 'git' }, 294 | folds = { 295 | open = false, 296 | git_hl = false, 297 | }, 298 | git = { 299 | patterns = { 'GitSign', 'MiniDiffSign' }, 300 | }, 301 | refresh = 50, 302 | }, 303 | terminal = { enabled = false }, 304 | toggle = { enabled = false }, 305 | win = { enabled = true }, 306 | words = { enabled = false }, 307 | zen = { 308 | enabled = true, 309 | toggles = { 310 | dim = true, 311 | git_signs = false, 312 | mini_diff_signs = false, 313 | -- diagnostics = false, 314 | -- inlay_hints = false, 315 | }, 316 | show = { 317 | statusline = false, 318 | tabline = false, 319 | }, 320 | win = { style = 'zen' }, 321 | zoom = { 322 | toggles = {}, 323 | show = { statusline = true, tabline = true }, 324 | win = { 325 | backdrop = false, 326 | width = 0, 327 | }, 328 | }, 329 | }, 330 | }) 331 | -------------------------------------------------------------------------------- /lua/plugins/ui/which-key.lua: -------------------------------------------------------------------------------- 1 | local which_key = require('which-key') 2 | local icons = require('lib.icons') 3 | local util = require('lib.util') 4 | local prompts = require('lib.prompts') 5 | 6 | local setup = { 7 | preset = 'modern', 8 | plugins = { 9 | marks = true, 10 | registers = true, 11 | spelling = { 12 | enabled = true, 13 | suggestions = 30, 14 | }, 15 | presets = { 16 | operators = true, 17 | motions = true, 18 | text_objects = true, 19 | windows = true, 20 | nav = true, 21 | z = true, 22 | g = true, 23 | }, 24 | }, 25 | icons = { 26 | breadcrumb = icons.ui.ArrowOpen, 27 | separator = icons.ui.Arrow, 28 | group = '', 29 | keys = { 30 | Space = icons.ui.Rocket, 31 | }, 32 | rules = false, -- enable auto icon rules 33 | }, 34 | win = { 35 | no_overlap = true, 36 | border = 'rounded', 37 | width = 0.8, 38 | height = { min = 5, max = 25 }, 39 | padding = { 1, 2 }, 40 | title = true, 41 | title_pos = 'center', 42 | zindex = 1000, 43 | wo = { 44 | winblend = 10, 45 | }, 46 | }, 47 | layout = { 48 | width = { min = 20 }, 49 | spacing = 6, 50 | align = 'center', 51 | }, 52 | show_help = false, 53 | show_keys = true, 54 | triggers = { 55 | { '', mode = 'nvisoct' }, 56 | { '', mode = { 'n', 'v' } }, 57 | }, 58 | } 59 | 60 | local normal_mappings = { 61 | mode = 'n', 62 | { 'x', ':x', desc = ' Save and Quit' }, 63 | 64 | { 'a', group = ' AI' }, 65 | { 'aC', ':AvanteClear', desc = 'avante: clear' }, 66 | { 'am', ':MCPHub', desc = 'MCPHub' }, 67 | { 'an', ':AvanteChatNew', desc = 'avante: new' }, 68 | { 'ap', group = 'Insert Prompt' }, 69 | { 'apd', prompts.add_prompt('docs'), desc = 'Docs' }, 70 | { 'ape', prompts.add_prompt('explain'), desc = 'Explain' }, 71 | { 'apf', prompts.add_prompt('fix'), desc = 'Fix' }, 72 | { 'apg', prompts.add_prompt('commit'), desc = 'Commit' }, 73 | { 'apo', prompts.add_prompt('optimize'), desc = 'Optimize' }, 74 | { 'apr', prompts.add_prompt('review'), desc = 'Review' }, 75 | { 'apt', prompts.add_prompt('tests'), desc = 'Tests' }, 76 | 77 | { 'c', group = ' Code' }, 78 | { 'cF', ':retab', desc = 'Fix Tabs' }, 79 | { 'cP', ':CccConvert', desc = 'Convert Color' }, 80 | { 'cR', ':ReloadConfig', desc = 'Reload Configs' }, 81 | { 'cc', ':CccHighlighterToggle', desc = 'Highlight Colors' }, 82 | { 'cd', ':RootDir', desc = 'Root Directory' }, 83 | { 'ce', ':%SnipRun', desc = 'Execute File' }, 84 | { 'cf', ':lua vim.lsp.buf.format({async = true})', desc = 'Format File' }, 85 | { 'cl', '::g/^\\s*$/d', desc = 'Clean Empty Lines' }, 86 | { 'cm', ':MarkdownPreviewToggle', desc = 'Markdown Preview' }, 87 | { 'co', ':Dashboard', desc = 'Dashboard' }, 88 | { 'cp', ':CccPick', desc = 'Pick Color' }, 89 | { 'cs', ':source %', desc = 'Source File' }, 90 | 91 | { 'e', group = ' Edit' }, 92 | { 'ea', ':b#', desc = 'Alternate File' }, 93 | { 'ec', group = 'Edit Configs' }, 94 | { 'eca', ':e ~/.config/shell/aliases.sh', desc = 'Shell Aliases' }, 95 | { 'ecA', ':e ~/.config/alacritty/alacritty.toml', desc = 'Alacritty Config' }, 96 | { 'ecb', ':e ~/.bashrc', desc = 'Bash Config' }, 97 | { 'ece', ':e ~/.config/shell/environment.sh', desc = 'Environment Config' }, 98 | { 'ecf', ':e ~/.config/shell/functions.sh', desc = 'Shell Functions' }, 99 | { 'ecg', ':e ~/.gitconfig', desc = 'Git Config' }, 100 | { 'eck', ':e ~/.config/kitty/kitty.conf', desc = 'Kitty Config' }, 101 | { 'ecl', ':e ~/.config/shell/local.sh', desc = 'Local Env' }, 102 | { 'ecn', ':e $MYVIMRC', desc = 'Neovim Init' }, 103 | { 'ecp', ':e ~/.config/nvim/lua/plugins/list.lua', desc = 'Plugin List' }, 104 | { 'ecq', ':e ~/.config/qutebrowser/config.py', desc = 'Qutebrowser Config' }, 105 | { 'ect', ':e ~/.config/tmux/tmux.conf', desc = 'Tmux Config' }, 106 | { 'ecv', ':e ~/.vimrc', desc = 'Vim Config' }, 107 | { 'ecz', ':e $ZDOTDIR/.zshrc', desc = 'Zsh Config' }, 108 | { 'ecZ', ':e $ZDOTDIR/prompt/init.zsh', desc = 'Zsh Prompt Config' }, 109 | { 'eE', ':lua Snacks.explorer()', desc = 'File Explorer' }, 110 | { 'et', ':lua MiniFiles.open()', desc = 'Explore Tree' }, 111 | { 'ef', 'gf', desc = 'File Under Cursor' }, 112 | { 'em', ':e README.md', desc = 'Readme' }, 113 | { 'en', ':enew', desc = 'New File' }, 114 | 115 | { 'f', group = ' Find' }, 116 | { 'fx', ':%bd|e#|bd#', desc = 'Close except current' }, 117 | 118 | { 'g', group = ' Git' }, 119 | { 'gA', ':Gitsigns stage_buffer', desc = 'Stage Buffer' }, 120 | { 'gC', ':CoAuthor', desc = 'Co-Authors' }, 121 | { 'gP', ':Git push', desc = 'Push' }, 122 | { 'gR', ':Gitsigns reset_buffer', desc = 'Reset Buffer' }, 123 | { 'ga', ':Gitsigns stage_hunk', desc = 'Stage Hunk' }, 124 | { 'gb', ":lua require('gitsigns').blame_line({full = true})", desc = 'Blame' }, 125 | { 'gc', ':Git commit', desc = 'Commit Staged' }, 126 | { 'gB', ":lua require('snacks').git.blame_line()", desc = 'Detailed Blame' }, 127 | { 'gd', ':Gitsigns diffthis HEAD', desc = 'Git Diff' }, 128 | { 'gF', ':Git', desc = 'Fugitive Panel' }, 129 | { 'gg', ':lua require("snacks").lazygit()', desc = 'Lazygit' }, 130 | { 'gi', ':Gitsigns preview_hunk', desc = 'Hunk Info' }, 131 | { 'gj', ':Gitsigns next_hunk', desc = 'Next Hunk' }, 132 | { 'gk', ':Gitsigns prev_hunk', desc = 'Prev Hunk' }, 133 | { 'go', group = 'Octohub' }, 134 | { 'gp', ':Git pull', desc = 'Pull' }, 135 | { 'gr', ':Gitsigns reset_hunk', desc = 'Reset Hunk' }, 136 | { 'gt', group = 'Toggle' }, 137 | { 'gtb', ':Gitsigns toggle_current_line_blame', desc = 'Blame' }, 138 | { 'gtd', ':Gitsigns toggle_deleted', desc = 'Deleted' }, 139 | { 'gtl', ':Gitsigns toggle_linehl', desc = 'Line HL' }, 140 | { 'gtn', ':Gitsigns toggle_numhl', desc = 'Number HL' }, 141 | { 'gts', ':Gitsigns toggle_signs', desc = 'Signs' }, 142 | { 'gtw', ':Gitsigns toggle_word_diff', desc = 'Word Diff' }, 143 | { 'gu', ':Gitsigns undo_stage_hunk', desc = 'Undo Stage Hunk' }, 144 | { 'gv', ':Gitsigns select_hunk', desc = 'Select Hunk' }, 145 | { 'gw', ':lua require("snacks").gitbrowse()', desc = 'Git Browse' }, 146 | 147 | { 'i', group = ' Insert' }, 148 | { 'id', ":put =strftime('## %a, %d %b, %Y, %r')", desc = 'Date' }, 149 | { 'if', ":put =expand('%:t')", desc = 'File Name' }, 150 | { 'in', ':Nerdy', desc = 'Nerd Glyphs' }, 151 | { 'ip', ':put %', desc = 'Relative Path' }, 152 | { 'iP', ':put %:p', desc = 'Absolute Path' }, 153 | { 'it', ":put =strftime('## %r')", desc = 'Time' }, 154 | 155 | { 'j', group = ' Jump' }, 156 | { 'jc', '*', desc = 'Word' }, 157 | { 'jd', ':FlashDiagnostics', desc = 'Diagnostics' }, 158 | { 'jh', '', desc = 'Backward' }, 159 | { 'jj', ":lua require('flash').remote()", desc = 'Remote' }, 160 | { 'jk', ":lua require('flash').treesitter()", desc = 'Treesitter' }, 161 | { 'jl', '', desc = 'Forward' }, 162 | { 'jp', ":lua require('flash').jump({continue = true})", desc = 'Previous Jump' }, 163 | { 'js', ":lua require('flash').jump()", desc = 'Search' }, 164 | { 'jt', ":lua require('flash').treesitter_search()", desc = 'Remote Treesitter' }, 165 | { 166 | 'jn', 167 | ":lua require('flash').jump({search = { forward = true, wrap = false, multi_window = false },})", 168 | desc = 'Search Forward', 169 | }, 170 | { 171 | 'jN', 172 | ":lua require('flash').jump({search = { forward = false, wrap = false, multi_window = false },})", 173 | desc = 'Search Backward', 174 | }, 175 | { 176 | 'jw', 177 | ':lua require("flash").jump({ pattern = vim.fn.expand("")})', 178 | desc = 'Current Word', 179 | }, 180 | 181 | { 'l', group = ' LSP' }, 182 | { 'la', ':Lspsaga code_action', desc = 'Code Action' }, 183 | { 'ld', ':Lspsaga goto_definition', desc = 'Goto Definition' }, 184 | { 'lf', ':Lspsaga finder', desc = 'Finder' }, 185 | { 'lh', ':Lspsaga hover_doc', desc = 'Hover' }, 186 | { 'lI', ':LspInfo', desc = 'LSP Info' }, 187 | { 'lj', ':Lspsaga diagnostic_jump_next', desc = 'Next Diagnostic' }, 188 | { 'lk', ':Lspsaga diagnostic_jump_prev', desc = 'Prev Diagnostic' }, 189 | { 'lo', ':Lspsaga outline', desc = 'Outline' }, 190 | { 'lp', ':Lspsaga peek_definition', desc = 'Peek Definition' }, 191 | { 'lq', ':LspStop', desc = 'Stop LSP' }, 192 | { 'lQ', ':LspRestart', desc = 'Restart LSP' }, 193 | { 'lr', ':Lspsaga rename', desc = 'Rename' }, 194 | { 'lR', ':Lspsaga project_replace', desc = 'Replace' }, 195 | { 'lt', ':Lspsaga goto_type_definition', desc = 'Goto Type Definition' }, 196 | { 'lT', ':Lspsaga peek_type_definition', desc = 'Peek Type Definition' }, 197 | 198 | { 'm', group = ' Marks' }, 199 | { 200 | 'mb', 201 | ":lua require('telescope').extensions.markit.bookmarks_list_all()", 202 | desc = 'Bookmarks', 203 | }, 204 | { 205 | 'mB', 206 | ":lua require('telescope').extensions.markit.bookmarks_list_all({project_only = true})", 207 | desc = 'Bookmarks In Project', 208 | }, 209 | { 'md', ":lua require('markit').delete_line()", desc = 'Delete Marks In Line' }, 210 | { 'mD', ":lua require('markit').delete_buf()", desc = 'Delete Marks In Buffer' }, 211 | { 'mg', group = 'Group Bookmarks' }, 212 | { 'mG', group = 'Group Bookmarks In Project' }, 213 | { 'mh', ":lua require('markit').prev_bookmark()", desc = 'Previous Bookmark' }, 214 | { 'mj', ":lua require('markit').next()", desc = 'Next' }, 215 | { 'mk', ":lua require('markit').prev()", desc = 'Previous' }, 216 | { 'ml', ":lua require('markit').next_bookmark()", desc = 'Next Bookmark' }, 217 | { 'mn', group = 'Next Bookmark In Group' }, 218 | { 'mp', group = 'Previous Bookmark In Group' }, 219 | { 'mP', ":lua require('markit').preview()", desc = 'Preview' }, 220 | { 'ms', ":lua require('markit').set_next()", desc = 'Set Next' }, 221 | { 'mt', ":lua require('markit').toggle()", desc = 'Toggle' }, 222 | { 'mx', ":lua require('markit').delete_bookmark()", desc = 'Delete Bookmark' }, 223 | 224 | { 'n', group = ' Notes' }, 225 | { 'na', ':lua Snacks.scratch.select()', desc = 'Select Scratch' }, 226 | { 227 | 'nc', 228 | ':lua require("tdo").run_with("commit " .. vim.fn.expand("%:p")) vim.notify("Committed!")', 229 | desc = 'Commit Note', 230 | }, 231 | { 'nd', ':Tdo', desc = "Today's Todo" }, 232 | { 'ne', ':TdoEntry', desc = "Today's Entry" }, 233 | { 'nf', ':TdoFiles', desc = 'All Notes' }, 234 | { 'ng', ':TdoFind', desc = 'Find Notes' }, 235 | { 'nh', ':Tdo -1', desc = "Yesterday's Todo" }, 236 | { 'nl', ':Tdo 1', desc = "Tomorrow's Todo" }, 237 | { 'nn', ':TdoNote', desc = 'New Note' }, 238 | { 'np', group = 'Past Todos' }, 239 | { 'ns', ':lua Snacks.scratch()', desc = 'New Scratch' }, 240 | { 'nt', ':TdoTodos', desc = 'Incomplete Todos' }, 241 | { 'nx', ':TdoToggle', desc = 'Toggle Todo' }, 242 | 243 | { 'o', group = ' Options' }, 244 | { 'oi', 'vim.show_pos', desc = 'Inspect Position' }, 245 | { 'oN', ':lua Snacks.notifier.show_history()', desc = 'Notification History' }, 246 | { 'or', ':set relativenumber!', desc = 'Relative Numbers' }, 247 | 248 | { 'p', group = ' Packages' }, 249 | { 'pc', ':Lazy check', desc = 'Check' }, 250 | { 'pd', ':Lazy debug', desc = 'Debug' }, 251 | { 'pe', ':lua require("snacks").profiler.scratch()', desc = 'Profiler Scratch' }, 252 | { 'pf', ':lua require("snacks").profiler.pick()', desc = 'Profiler Pick' }, 253 | { 'pi', ':Lazy install', desc = 'Install' }, 254 | { 'pl', ':Lazy log', desc = 'Log' }, 255 | { 'pm', ':Mason', desc = 'Mason' }, 256 | { 'pp', ':Lazy', desc = 'Plugins' }, 257 | { 'pP', ':Lazy profile', desc = 'Profile' }, 258 | { 'pr', ':Lazy restore', desc = 'Restore' }, 259 | { 'ps', ':Lazy sync', desc = 'Sync' }, 260 | { 'pt', ':lua require("snacks").profiler.toggle()', desc = 'Profiler Toggle' }, 261 | { 'pu', ':Lazy update', desc = 'Update' }, 262 | { 'px', ':Lazy clean', desc = 'Clean' }, 263 | 264 | { 'q', group = ' Quit' }, 265 | { 'qa', ':qall', desc = 'Quit All' }, 266 | { 'qb', ':bw', desc = 'Close Buffer' }, 267 | { 'qd', ':lua require("snacks").bufdelete()', desc = 'Delete Buffer' }, 268 | { 'qf', ':qall!', desc = 'Force Quit' }, 269 | { 'qo', ':%bdelete|b#|bdelete#', desc = 'Close Others' }, 270 | { 'qq', ':q', desc = 'Quit' }, 271 | { 'qs', 'c', desc = 'Close Split' }, 272 | { 'qw', ':wq', desc = 'Write and Quit' }, 273 | 274 | { 'r', group = ' Refactor' }, 275 | { 'ra', ":lua require('spectre').open()", desc = 'Replace All' }, 276 | { 'rb', ":lua require('spectre').open_file_search()", desc = 'Replace Buffer' }, 277 | { 'rd', '', desc = 'Go To Definition' }, -- treesitter navigation 278 | { 'rh', '', desc = 'List Definition Head' }, 279 | { 'rj', '', desc = 'Next Usage' }, 280 | { 'rk', '', desc = 'Previous Usage' }, 281 | { 'rl', '', desc = 'List Definition' }, 282 | { 'rn', '', desc = 'Swap Next' }, 283 | { 'rp', '', desc = 'Swap Previous' }, 284 | { 'rr', '', desc = 'Smart Rename' }, 285 | { 'rs', ':%s/\\<\\>//gI', desc = 'Replace Word Buffer' }, 286 | { 'rw', ":lua require('spectre').open_visual({select_word=true})", desc = 'Replace Word Everywhere' }, 287 | 288 | { 's', group = ' Split' }, 289 | { 's+', ':resize +10', desc = 'Increase window height' }, 290 | { 's-', ':vertical resize -20', desc = 'Decrease window width' }, 291 | { 's/', 's', desc = 'Split Below' }, 292 | { 's=', ':vertical resize +20', desc = 'Increase window width' }, 293 | { 'sH', ':vertical resize -10', desc = 'Decrease window width' }, 294 | { 'sJ', ':resize -5', desc = 'Decrease window height' }, 295 | { 'sK', ':resize +5', desc = 'Increase window height' }, 296 | { 'sL', ':vertical resize +10', desc = 'Increase window width' }, 297 | { 's\\', 'v', desc = 'Split Right' }, 298 | { 's_', ':resize -10', desc = 'Decrease window height' }, 299 | { 's`', 'p', desc = 'Previous Window' }, 300 | { 'sa', ':split', desc = 'Horizontal Split' }, 301 | { 'sc', ':tabclose', desc = 'Close Tab' }, 302 | { 'sf', ':tabfirst', desc = 'First Tab' }, 303 | { 'sh', 'h', desc = 'Move Left' }, 304 | { 'sj', 'j', desc = 'Move Down' }, 305 | { 'sk', 'k', desc = 'Move Up' }, 306 | { 'sl', 'l', desc = 'Move Right' }, 307 | { 'sp', ':NavigatorPrevious', desc = 'Previous Pane' }, 308 | { 'sq', 'c', desc = 'Close Split' }, 309 | { 'ss', ':vsplit', desc = 'Vertical Split' }, 310 | 311 | { 't', group = ' Terminal' }, 312 | { 't`', ':Sterm', desc = 'Horizontal Terminal' }, 313 | { 'tc', ':Sterm bundle exec rails console', desc = 'Rails Console' }, 314 | { 'td', ':Sterm dexe', desc = 'Exe Launcher' }, 315 | { 'tn', ':Sterm node', desc = 'Node' }, 316 | { 'tp', ':Sterm bpython', desc = 'Python' }, 317 | { 'tr', ':Sterm irb', desc = 'Ruby' }, 318 | { 'ts', ':Sterm', desc = 'Horizontal Terminal' }, 319 | { 'tt', ':Fterm', desc = 'Terminal' }, 320 | { 'tv', ':Vterm', desc = 'Vertical Terminal' }, 321 | { 'tw', ':Sterm dexe --wait-before-exit', desc = 'Exe Launcher, Wait' }, 322 | 323 | { 'w', group = ' Writing' }, 324 | { 'wc', ':set spell!', desc = 'Spellcheck' }, 325 | { 'wd', ':lua require("snacks").dim.enable()', desc = 'Dim On' }, 326 | { 'wD', ':lua require("snacks").dim.disable()', desc = 'Dim Off' }, 327 | { 'wf', ":lua require'utils'.sudo_write()", desc = 'Force Write' }, 328 | { 'wj', ']s', desc = 'Next Misspell' }, 329 | { 'wk', '[s', desc = 'Prev Misspell' }, 330 | { 'wn', ':WriteNoFormat', desc = 'Write Without Formatting' }, 331 | { 'wq', ':wq', desc = 'Write and Quit' }, 332 | { 'ww', ':w', desc = 'Write' }, 333 | { 'wz', ':lua require("snacks").zen.zen()', desc = 'Zen' }, 334 | { 'wZ', ':lua require("snacks").zen.zoom()', desc = 'Zoom' }, 335 | 336 | { 'y', group = ' Yank' }, 337 | { 'yL', ':CopyAbsolutePathWithLine', desc = 'Absolute Path with Line' }, 338 | { 'yP', ':CopyAbsolutePath', desc = 'Absolute Path' }, 339 | { 'ya', ':%y+', desc = 'Copy Whole File' }, 340 | { 'yf', ':CopyFileName', desc = 'File Name' }, 341 | { 'yg', ':lua require"gitlinker".get_buf_range_url()', desc = 'Copy Git URL' }, 342 | { 'yl', ':CopyRelativePathWithLine', desc = 'Relative Path with Line' }, 343 | { 'yp', ':CopyRelativePath', desc = 'Relative Path' }, 344 | } 345 | 346 | -- Numerical mappings 347 | for i = 1, 9 do 348 | table.insert(normal_mappings, { 349 | string.format('n%d', i), 350 | string.format(':Tdo %d', i), 351 | desc = string.format('Todo %d Days In Future', i), 352 | }) 353 | 354 | table.insert(normal_mappings, { 355 | string.format('np%d', i), 356 | string.format(':Tdo -%d', i), 357 | desc = string.format('Todo %d Days From Past', i), 358 | }) 359 | 360 | table.insert(normal_mappings, { 361 | string.format('f%d', i), 362 | string.format(':LualineBuffersJump%d', i), 363 | desc = string.format('File %d', i), 364 | }) 365 | 366 | table.insert(normal_mappings, { 367 | string.format('m%d', i), 368 | string.format(':lua require("markit").toggle_bookmark%d()', i), 369 | desc = string.format('Toggle Group %d Bookmark', i), 370 | }) 371 | 372 | table.insert(normal_mappings, { 373 | string.format('mp%d', i), 374 | string.format(':lua require("markit").prev_bookmark%d()', i), 375 | desc = string.format('Previous Group %d Bookmarks', i), 376 | }) 377 | 378 | table.insert(normal_mappings, { 379 | string.format('mn%d', i), 380 | string.format(':lua require("markit").next_bookmark%d()', i), 381 | desc = string.format('Next Group %d Bookmarks', i), 382 | }) 383 | 384 | table.insert(normal_mappings, { 385 | string.format('mg%d', i), 386 | string.format(':lua require("telescope").extensions.markit.bookmarks_list_all({group = %d})', i), 387 | desc = string.format('Group %d Bookmarks', i), 388 | }) 389 | 390 | table.insert(normal_mappings, { 391 | string.format('mG%d', i), 392 | string.format( 393 | ':lua require("telescope").extensions.markit.bookmarks_list_all({group = %d, project_only = true})', 394 | i 395 | ), 396 | desc = string.format('Group %d Bookmarks In Project', i), 397 | }) 398 | end 399 | 400 | local visual_mappings = { 401 | mode = 'v', 402 | { 'a', group = ' AI' }, 403 | 404 | { 'c', group = ' Code' }, 405 | { 'ce', ":'<,'>SnipRun", desc = 'Execute Selection' }, 406 | { 'cS', ':sort!', desc = 'Sort Desc' }, 407 | { 'ci', ':sort i', desc = 'Sort Case Insensitive' }, 408 | { 'cs', ':sort', desc = 'Sort Asc' }, 409 | { 'cu', ':!uniq', desc = 'Unique' }, 410 | { 'cx', ':lua', desc = 'Execute Lua' }, 411 | 412 | { 'g', group = ' Git' }, 413 | { 'ga', ":'<,'>Gitsigns stage_hunk", desc = 'Stage Hunk' }, 414 | { 'gr', ":'<,'>Gitsigns reset_hunk", desc = 'Reset Hunk' }, 415 | { 'gu', ":'<,'>Gitsigns undo_stage_hunk", desc = 'Undo Stage Hunk' }, 416 | 417 | { 'j', group = ' Jump' }, 418 | { 419 | 'jN', 420 | ":lua require('flash').jump({search = { forward = false, wrap = false, multi_window = false },})", 421 | desc = 'Search Backward', 422 | }, 423 | { 'jd', ':FlashDiagnostics', desc = 'Diagnostics' }, 424 | { 'jj', ":lua require('flash').remote()", desc = 'Remote' }, 425 | { 'jk', ":lua require('flash').treesitter()", desc = 'Treesitter' }, 426 | { 427 | 'jn', 428 | ":lua require('flash').jump({search = { forward = true, wrap = false, multi_window = false },})", 429 | desc = 'Search Forward', 430 | }, 431 | { 'jp', ":lua require('flash').jump({continue = true})", desc = 'Previous Jump' }, 432 | { 'js', ":lua require('flash').jump()", desc = 'Search' }, 433 | { 'jt', ":lua require('flash').treesitter_search()", desc = 'Remote Treesitter' }, 434 | { 435 | 'jw', 436 | ':lua require("flash").jump({ pattern = vim.fn.expand("")})', 437 | desc = 'Current Word', 438 | }, 439 | 440 | { 'l', group = ' LSP' }, 441 | { 'la', ':Lspsaga range_code_action', desc = 'Code Action' }, 442 | 443 | { 'y', group = ' Yank' }, 444 | { 'yg', ':lua require"gitlinker".get_buf_range_url("v")', desc = 'Copy Git URL' }, 445 | } 446 | 447 | local no_leader_mappings = { 448 | mode = 'n', 449 | { '', ':resize -10', desc = 'Decrease window height' }, 450 | { '', ':vertical resize -10', desc = 'Decrease window width' }, 451 | { '', ':vertical resize +10', desc = 'Increase window width' }, 452 | { '', ':resize +10', desc = 'Increase window height' }, 453 | { '', ':Fterm lazygit', desc = 'Lazygit' }, 454 | 455 | { '', ':NavigatorLeft', desc = 'Move Left' }, 456 | { '', ':NavigatorDown', desc = 'Move Down' }, 457 | { '', ':NavigatorUp', desc = 'Move Up' }, 458 | { '', ':NavigatorRight', desc = 'Move Right' }, 459 | { '', ':NavigatorPrevious', desc = 'Previous Pane' }, 460 | 461 | { '', ':bprevious', desc = 'Previous Buffer' }, 462 | { '', ':bnext', desc = 'Next Buffer' }, 463 | 464 | { 'K', ':Lspsaga hover_doc', desc = 'LSP Hover' }, 465 | { 'Q', ':qall!', desc = 'Force Quit!' }, 466 | { 'U', ':redo', desc = 'Redo' }, 467 | 468 | { '[', group = ' Previous' }, 469 | { '[g', ':Gitsigns prev_hunk', desc = 'Git Hunk' }, 470 | { '[o', group = 'Textobjects' }, 471 | 472 | { ']', group = ' Next' }, 473 | { ']g', ':Gitsigns next_hunk', desc = 'Git Hunk' }, 474 | { ']o', group = 'Textobjects' }, 475 | 476 | { 'gd', ':Lspsaga goto_definition', desc = 'Goto Definition' }, 477 | } 478 | 479 | which_key.setup(setup) 480 | which_key.add(normal_mappings) 481 | which_key.add(visual_mappings) 482 | which_key.add(no_leader_mappings) 483 | 484 | if util.get_user_config('enable_test_runner', false) then 485 | local test_runner_bindings = { 486 | mode = 'n', 487 | { 'u', group = ' Test' }, 488 | { 'uc', ':lua require("neotest").run.run()', desc = 'Run Current Test' }, 489 | { 'uf', ':lua require("neotest").run.run(vim.fn.expand("%"))', desc = 'Run Test File' }, 490 | { 'uo', ':Neotest output-panel', desc = 'Test Output' }, 491 | { 'us', ':Neotest summary', desc = 'Test Summary' }, 492 | } 493 | which_key.add(test_runner_bindings) 494 | end 495 | 496 | if util.get_user_config('enable_db_explorer', false) then 497 | local db_explorer_bindings = { 498 | mode = 'n', 499 | { 'd', group = ' Database' }, 500 | { 'dS', ':lua require("dbee").store("json", "buffer", { extra_arg = 0 })', desc = 'To JSON' }, 501 | { 'db', ':DBToggle', desc = 'DB Explorer' }, 502 | { 'dj', ':lua require("dbee").next()', desc = 'DB Next' }, 503 | { 'dk', ':lua require("dbee").prev()', desc = 'DB Prev' }, 504 | { 'ds', ':lua require("dbee").store("csv", "buffer", { extra_arg = 0 })', desc = 'To CSV' }, 505 | { 'dt', ':lua require("dbee").store("table", "buffer", { extra_arg = 0 })', desc = 'To Table' }, 506 | } 507 | which_key.add(db_explorer_bindings) 508 | end 509 | 510 | if util.get_user_config('enable_debugger', false) then 511 | local debugger_bindings = { 512 | mode = 'n', 513 | { 'b', group = ' Debug' }, 514 | { 'bO', ':DapStepOut', desc = 'Out' }, 515 | { 'bR', ':DapRestartFrame', desc = 'Restart Frame' }, 516 | { 'bb', ':DapToggleBreakpoint', desc = 'Breakpoint' }, 517 | { 'bc', ':DapContinue', desc = 'Continue' }, 518 | { 'bi', ':DapStepInto', desc = 'Into' }, 519 | { 'bl', ":lua require'dap'.run_last()", desc = 'Last' }, 520 | { 'bo', ':DapStepOver', desc = 'Over' }, 521 | { 'br', ':DapToggleRepl', desc = 'Repl' }, 522 | { 'bt', ':DapUIToggle', desc = 'Debugger' }, 523 | { 'bx', ':DapTerminate', desc = 'Exit' }, 524 | } 525 | which_key.add(debugger_bindings) 526 | end 527 | 528 | local user_keybindings = require('lib.util').get_user_config('user_keybindings', {}) 529 | which_key.add(user_keybindings) 530 | -------------------------------------------------------------------------------- /plugin/after/highlights.lua: -------------------------------------------------------------------------------- 1 | -- transparent background 2 | vim.api.nvim_set_hl(0, 'Normal', { bg = 'none' }) 3 | vim.api.nvim_set_hl(0, 'NormalFloat', { bg = 'none' }) 4 | vim.api.nvim_set_hl(0, 'FloatBorder', { bg = 'none' }) 5 | vim.api.nvim_set_hl(0, 'Pmenu', { bg = 'none' }) 6 | vim.api.nvim_set_hl(0, 'Terminal', { bg = 'none' }) 7 | vim.api.nvim_set_hl(0, 'EndOfBuffer', { bg = 'none' }) 8 | vim.api.nvim_set_hl(0, 'FoldColumn', { bg = 'none' }) 9 | vim.api.nvim_set_hl(0, 'Folded', { bg = 'none' }) 10 | vim.api.nvim_set_hl(0, 'SignColumn', { bg = 'none' }) 11 | 12 | -- transparent background for nvim-tree 13 | vim.api.nvim_set_hl(0, 'NvimTreeNormal', { bg = 'none' }) 14 | vim.api.nvim_set_hl(0, 'NvimTreeVertSplit', { bg = 'none' }) 15 | vim.api.nvim_set_hl(0, 'NvimTreeEndOfBuffer', { bg = 'none' }) 16 | 17 | -- set hlsearch color 18 | vim.api.nvim_set_hl(0, 'Search', { bg = '#8BCD5B', fg = '#202020' }) 19 | vim.api.nvim_set_hl(0, 'CurSearch', { bg = '#EFBD5D', fg = '#000000' }) 20 | vim.api.nvim_set_hl(0, 'IncSearch', { bg = '#F15664', fg = '#000000' }) 21 | 22 | -- set cursorline color 23 | vim.api.nvim_set_hl(0, 'CursorLine', { bg = '#1A1A1F' }) 24 | vim.api.nvim_set_hl(0, 'CursorColumn', { bg = '#1A1A1F' }) 25 | 26 | -- set visual highlight 27 | vim.api.nvim_set_hl(0, 'Visual', { bg = '#103070' }) 28 | 29 | --------------------------------------------------------------------------------