This commit is contained in:
jmarkin 2025-09-06 13:48:36 +03:00
commit 78428a99f0
154 changed files with 19525 additions and 0 deletions

2
.envrc Normal file
View file

@ -0,0 +1,2 @@
watch_file nix/*
use flake . -Lv

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
result
.direnv
.luarc.json

6
.stylua.toml Normal file
View file

@ -0,0 +1,6 @@
column_width = 120
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 2
quote_style = "AutoPreferDouble"
call_parentheses = "Always"

339
LICENSE Normal file
View file

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

10
Makefile Normal file
View file

@ -0,0 +1,10 @@
tests-data: tests/data/bigdata.json tests/data/bigdata.yml
tests/data/bigdata.json:
+mkdir -p tests/data
+curl -L --progress-bar -o $@ \
"https://raw.githubusercontent.com/miloyip/nativejson-benchmark/master/data/canada.json"
tests/data/bigdata.yml:
+mkdir -p tests/data
+base64 /dev/urandom | head --bytes $$(( 5*1024*1024 )) > $@

332
README.md Normal file
View file

@ -0,0 +1,332 @@
<!-- markdownlint-disable -->
<br />
<div align="center">
<a href="https://github.com/nix-community/kickstart-nix.nvim">
<img src="./nvim-nix.svg" alt="kickstart-nix.nvim">
</a>
<!-- TODO: -->
<!-- <p align="center"> -->
<!-- <br /> -->
<!-- TODO: -->
<!-- <a href="./nvim/doc/kickstart-nix.txt"><strong>Explore the docs »</strong></a> -->
<!-- <br /> -->
<!-- <br /> -->
<!-- <a href="https://github.com/nix-community/kickstart-nix.nvim/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml">Report Bug</a> -->
<!-- · -->
<!-- <a href="https://github.com/nix-community/kickstart-nix.nvim/issues/new?assignees=&labels=enhancement&projects=&template=feature_request.yml">Request Feature</a> -->
<!-- · -->
<!-- <a href="https://github.com/nix-community/kickstart-nix.nvim/discussions/new?category=q-a">Ask Question</a> -->
<!-- </p> -->
<p>❄️</p>
<p>
<strong>
A dead simple <a href="https://nixos.org/">Nix</a> flake template repository</br>
for <a href="https://neovim.io/">Neovim</a>
</strong>
</p>
[![Neovim][neovim-shield]][neovim-url]
[![Nix][nix-shield]][nix-url]
[![Lua][lua-shield]][lua-url]
[![GPL2 License][license-shield]][license-url]
[![Issues][issues-shield]][issues-url]
</div>
<!-- markdownlint-restore -->
![](https://github.com/nix-community/kickstart-nix.nvim/assets/12857160/84faa268-82de-4401-acf3-efddc26dd58a)
## :grey_question: Why kickstart-nix.nvim
If Nix and Neovim have one thing in common,
it's that many new users don't know where to get started.
Most Nix-based Neovim setups assume deep expertise in both realms,
abstracting away Neovim's core functionalities
as well as the Nix internals used to build a Neovim config.
Frameworks and module-based DSLs are opinionated and difficult to diverge from
with one's own modifications.
`kickstart-nix.nvim` is different:
It's geared for users of all levels,
making the migration of Neovim configurations to Nix straightforward.
This project aims to be as simple as possible, while allowing
for maximum flexibility.
> [!NOTE]
>
> Similar to [`kickstart.nvim`](https://github.com/nvim-lua/kickstart.nvim),
> this repository is meant to be used by **you** to begin your
> **Nix**/Neovim journey; remove the things you don't use and add what you miss.
## :milky_way: Philosophy
- KISS principle with sane defaults.
- Manage plugins + external dependencies using Nix
(managing plugins shouldn't be the responsibility of a plugin).
- Configuration entirely in Lua[^1] (Vimscript is also possible).
This makes it easy to migrate from non-nix dotfiles.
- Use Neovim's built-in loading mechanisms. See:
- [`:h initialization`](https://neovim.io/doc/user/starting.html#initialization)
- [`:h runtimepath`](https://neovim.io/doc/user/options.html#'runtimepath')
- [`:h packadd`](https://neovim.io/doc/user/repeat.html#%3Apackadd)
- Use Neovim's built-in LSP client, with Nix managing language servers.
[^1]: The absence of a Nix module DSL for Neovim configuration is deliberate.
If you were to copy the `nvim` directory to `$XDG_CONFIG_HOME`,
and install the plugins, it would work out of the box.
## :star2: Features
- Use either nixpkgs or flake inputs as plugin sources.
- Usable on any device with Neovim and Nix installed.
- Create multiple derivations with different sets of plugins,
and simple regex filters to exclude config files.
- Uses Nix to generate a `.luarc.json` in the devShell's `shellHook`.
This sets up lua-language-server to recognize all plugins
and the Neovim API.
## :bicyclist: Test drive
If you have Nix installed (with [flakes](https://wiki.nixos.org/wiki/Flakes) enabled),
you can test drive this by running:
```console
nix run "github:nix-community/kickstart-nix.nvim"
```
## :books: Usage
1. Click on [Use this template](https://github.com/nix-community/kickstart-nix.nvim/generate)
to start a repo based on this template. **Do _not_ fork it**.
1. Add/remove plugins to/from the [Neovim overlay](./nix/neovim-overlay.nix).
1. Add/remove plugin configs to/from the `nvim/plugin` directory.
1. Modify as you wish (you will probably want to add a color theme, ...).
See: [Design](#robot-design).
1. You can create more than one package using the `mkNeovim` function by
- Passing different plugin lists.
- Adding `ignoreConfigRegexes` (e.g. `= [ "^ftplugin/.*.lua" ]`).
> [!TIP]
>
> The nix and lua files contain comments explaining
> what everything does in detail.
## :zap: Installation
### :snowflake: NixOS (with flakes)
1. Add your flake to you NixOS flake inputs.
1. Add the overlay provided by this flake.
```nix
nixpkgs.overlays = [
# replace <kickstart-nix-nvim> with the name you chose
<kickstart-nix-nvim>.overlays.default
];
```
You can then add the overlay's output(s) to the `systemPackages`:
```nix
environment.systemPackages = with pkgs; [
nvim-pkg # The default package added by the overlay
];
```
> [!IMPORTANT]
>
> This flake uses `nixpkgs.wrapNeovimUnstable`, which has an
> unstable signature. If you set `nixpkgs.follows = "nixpkgs";`
> when importing this into your flake.nix, it may break.
> Especially if your nixpkgs input pins a different branch.
### :penguin: Non-NixOS
With Nix installed (flakes enabled), from the repo root:
```console
nix profile install .#nvim
```
## :robot: Design
Directory structure:
```sh
── flake.nix
── nvim # Neovim configs (lua), equivalent to ~/.config/nvim
── nix # Nix configs
```
### :open_file_folder: Neovim configs
- Set options in `init.lua`.
- Source autocommands, user commands, keymaps,
and configure plugins in individual files within the `plugin` directory.
- Filetype-specific scripts (e.g. start LSP clients) in the `ftplugin` directory.
- Library modules in the `lua/user` directory.
Directory structure:
```sh
── nvim
├── ftplugin # Sourced when opening a file type
│ └── <filetype>.lua
├── init.lua # Always sourced
├── lua # Shared library modules
│ └── user
│ └── <lib>.lua
├── plugin # Automatically sourced at startup
│ ├── autocommands.lua
│ ├── commands.lua
│ ├── keymaps.lua
│ ├── plugins.lua # Plugins that require a `setup` call
│ └── <plugin-config>.lua # Plugin configurations
└── after # Empty in this template
├── plugin # Sourced at the very end of startup (rarely needed)
└── ftplugin # Sourced when opening a filetype, after sourcing ftplugin scripts
```
> [!IMPORTANT]
>
> - Configuration variables (e.g. `vim.g.<plugin_config>`) should go in `nvim/init.lua`
> or a module that is `require`d in `init.lua`.
> - Configurations for plugins that require explicit initialization
> (e.g. via a call to a `setup()` function) should go in `nvim/plugin/<plugin>.lua`
> or `nvim/plugin/plugins.lua`.
> - See [Initialization order](#initialization-order) for details.
### :open_file_folder: Nix
You can declare Neovim derivations in `nix/neovim-overlay.nix`.
There are two ways to add plugins:
- The traditional way, using `nixpkgs` as the source.
- By adding plugins as flake inputs (if you like living on the bleeding-edge).
Plugins added as flake inputs must be built manually.
Directory structure:
```sh
── flake.nix
── nix
├── mkNeovim.nix # Function for creating the Neovim derivation
└── neovim-overlay.nix # Overlay that adds Neovim derivation
```
### :mag: Initialization order
This derivation creates an `init.lua` as follows:
1. Add `nvim/lua` to the `runtimepath`.
1. Add the content of `nvim/init.lua`.
1. Add `nvim/*` to the `runtimepath`.
1. Add `nvim/after` to the `runtimepath`.
This means that modules in `nvim/lua` can be `require`d in `init.lua` and `nvim/*/*.lua`.
Modules in `nvim/plugin/` are sourced automatically, as if they were plugins.
Because they are added to the runtime path at the end of the resulting `init.lua`,
Neovim sources them _after_ loading plugins.
## :electric_plug: Pre-configured plugins
This configuration comes with [a few plugins pre-configured](./nix/neovim-overlay.nix).
You can add or remove plugins by
- Adding/Removing them in the [Nix list](./nix/neovim-overlay.nix).
- Adding/Removing the config in `nvim/plugin/<plugin>.lua`.
## :anchor: Syncing updates
If you have used this template and would like to fetch updates
that were added later...
Add this template as a remote:
```console
git remote add upstream git@github.com:nix-community/kickstart-nix.nvim.git
```
Fetch and merge changes:
```console
git fetch upstream
git merge upstream/main --allow-unrelated-histories
```
## :pencil: Editing your config
When your neovim setup is a nix derivation, editing your config
demands a different workflow than you are used to without nix.
A quick and easy way to test your changes:
- Perform modifications and stage any new files[^2].
- Run `nix run /path/to/neovim/#nvim`
or `nix run /path/to/neovim/#nvim -- <nvim-args>`
[^2]: When adding new files, nix flakes won't pick them up unless they
have been committed or staged.
This requires a rebuild of the `nvim` derivation, but has the advantage
that if anything breaks, it's only broken during your test run.
When developing locally you might want to have a faster feedback loop.
Normally the whole Neovim configuration is copied into the store and
the wrapper which nix generates for the derivation calls `nvim`
with `-u /nix/store/path/to/generated-init.lua`.
We can deactivate this behavior with `wrapRc = false`, so that the
config is loaded from `$XDG_CONFIG_HOME/$NVIM_APPNAME`[^3], where
`$NVIM_APPNAME` defaults to `nvim` if the `appName` attribute is not set
in the `mkNeovim` function.
The Flake exposes a dev shell with a `nvim-dev` package. The lua configuration in `./nvim`
is automatically symlinked to `~/.config/nvim-dev`.
After activating the shell with `nix develop` or [nix-direnv](https://github.com/nix-community/nix-direnv)
you can run Neovim with `nvim-dev` to automatically reload your lua configuration. All Nix changes still require a rebuild.
[^3]: Assuming Linux. Refer to `:h initialization` for Darwin.
## :link: Alternative / similar projects
- [`kickstart.nvim`](https://github.com/nvim-lua/kickstart.nvim):
Single-file Neovim configuration template with a similar philosophy to this project.
Does not use Nix to manage plugins.
- [`neovim-flake`](https://github.com/jordanisaacs/neovim-flake):
Configured using a Nix module DSL.
- [`NixVim`](https://github.com/nix-community/nixvim):
A module system for Neovim, with a focus on plugin configs.
- [`nixCats-nvim`](https://github.com/BirdeeHub/nixCats-nvim):
A project that organises plugins into categories.
It also separates lua and nix configuration.
- [`lz.n`](https://github.com/nvim-neorocks/lz.n):
A plugin-manager agnostic Lua library for lazy-loading plugins.
Can be used with Nix.
> [!NOTE]
>
> When comparing with projects in the "non-Nix world", this
> repository would be more comparable to `kickstart.nvim` (hence the name),
> while the philosophies of `neovim-flake` and `NixVim` are more in line with
> a Neovim distribution like [`LunarVim`](https://www.lunarvim.org/)
> or [`LazyVim`](https://www.lazyvim.org/)
> (though they are far more minimal by default).
<!-- MARKDOWN LINKS & IMAGES -->
[neovim-shield]: https://img.shields.io/badge/NeoVim-%2357A143.svg?&style=for-the-badge&logo=neovim&logoColor=white
[neovim-url]: https://neovim.io/
[nix-shield]: https://img.shields.io/badge/nix-0175C2?style=for-the-badge&logo=NixOS&logoColor=white
[nix-url]: https://nixos.org/
[lua-shield]: https://img.shields.io/badge/lua-%232C2D72.svg?style=for-the-badge&logo=lua&logoColor=white
[lua-url]: https://www.lua.org/
[license-shield]: https://img.shields.io/github/license/nix-community/kickstart-nix.nvim.svg?style=for-the-badge
[license-url]: https://github.com/nix-community/kickstart-nix.nvim/blob/master/LICENSE
[issues-shield]: https://img.shields.io/github/issues/nix-community/kickstart-nix.nvim.svg?style=for-the-badge
[issues-url]: https://github.com/nix-community/kickstart-nix.nvim/issues
[license-shield]: https://img.shields.io/github/license/nix-community/kickstart-nix.nvim.svg?style=for-the-badge
[license-url]: https://github.com/nix-community/kickstart-nix.nvim/blob/master/LICENSE

312
flake.lock Normal file
View file

@ -0,0 +1,312 @@
{
"nodes": {
"cmp-diag-codes": {
"flake": false,
"locked": {
"lastModified": 1684773141,
"narHash": "sha256-dqT0Z950n76vdisegSMv/ODBq5fYt1ITtaJdvdc0nCQ=",
"owner": "JMarkin",
"repo": "cmp-diag-codes",
"rev": "9842c4dc17848d23a413a823c2ef362c91dc81fd",
"type": "github"
},
"original": {
"owner": "JMarkin",
"repo": "cmp-diag-codes",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1717285511,
"narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gen-luarc": {
"inputs": {
"flake-parts": "flake-parts",
"git-hooks": "git-hooks",
"luvit-meta": "luvit-meta",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1755304025,
"narHash": "sha256-xVKfjFwc0zMbLMjLTiHz+0llggkjs93SmHkhaa9S3M4=",
"owner": "mrcjkb",
"repo": "nix-gen-luarc-json",
"rev": "1865b0ebb753ae5324d7381b1fa8c98c04ec7509",
"type": "github"
},
"original": {
"owner": "mrcjkb",
"repo": "nix-gen-luarc-json",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"gen-luarc",
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1723803910,
"narHash": "sha256-yezvUuFiEnCFbGuwj/bQcqg7RykIEqudOy/RBrId0pc=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "bfef0ada09e2c8ac55bbcd0831bd0c9d42e651ba",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"gen-luarc",
"git-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"hlargs-nvim": {
"flake": false,
"locked": {
"lastModified": 1750096091,
"narHash": "sha256-PEYo4tcawKgqATbKw46BIus+D0afP6Q0YSrlJ0WHAA4=",
"owner": "m-demare",
"repo": "hlargs.nvim",
"rev": "ce8d705866dae44513ff48613d5e37e4da524d70",
"type": "github"
},
"original": {
"owner": "m-demare",
"repo": "hlargs.nvim",
"type": "github"
}
},
"luvit-meta": {
"flake": false,
"locked": {
"lastModified": 1705776742,
"narHash": "sha256-zAAptV/oLuLAAsa2zSB/6fxlElk4+jNZd/cPr9oxFig=",
"owner": "Bilal2453",
"repo": "luvit-meta",
"rev": "ce76f6f6cdc9201523a5875a4471dcfe0186eb60",
"type": "github"
},
"original": {
"owner": "Bilal2453",
"repo": "luvit-meta",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1718714799,
"narHash": "sha256-FUZpz9rg3gL8NVPKbqU8ei1VkPLsTIfAJ2fdAf5qjak=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c00d587b1a1afbf200b1d8f0b0e4ba9deb1c7f0e",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1717284937,
"narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1720386169,
"narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "194846768975b7ad2c4988bdb82572c00222c0d7",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1756542300,
"narHash": "sha256-tlOn88coG5fzdyqz6R93SQL5Gpq+m/DsWpekNFhqPQk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d7600c775f877cd87b4f5a831c28aa94137377aa",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nvim-yati": {
"flake": false,
"locked": {
"lastModified": 1718009720,
"narHash": "sha256-hsSGj/bKY0FxZi1BlJxa/U2zvJzOwrFSz1W/MUtPunU=",
"owner": "yioneko",
"repo": "nvim-yati",
"rev": "df3dc06076c6fe20a1dcd8643e712af5c252d042",
"type": "github"
},
"original": {
"owner": "yioneko",
"repo": "nvim-yati",
"type": "github"
}
},
"root": {
"inputs": {
"cmp-diag-codes": "cmp-diag-codes",
"flake-utils": "flake-utils",
"gen-luarc": "gen-luarc",
"hlargs-nvim": "hlargs-nvim",
"nixpkgs": "nixpkgs_2",
"nvim-yati": "nvim-yati",
"rust-overlay": "rust-overlay",
"yaml-nvim": "yaml-nvim"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1757125853,
"narHash": "sha256-noKkYHKpT5lpvNSYrlH56d8cedthZfs010Uv6vTqLT4=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "8b70793a6be183536a5d562056dac10b7b36820d",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"yaml-nvim": {
"flake": false,
"locked": {
"lastModified": 1757087818,
"narHash": "sha256-UaJmX1gZ7ull6uu6OGJfiCFI5BV37FvoXPrSkxqSJ04=",
"owner": "cuducos",
"repo": "yaml.nvim",
"rev": "c6c7bac834c3f48e1afdb78a7a1d23996a2f89d9",
"type": "github"
},
"original": {
"owner": "cuducos",
"repo": "yaml.nvim",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

93
flake.nix Normal file
View file

@ -0,0 +1,93 @@
{
description = "Neovim derivation";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
gen-luarc.url = "github:mrcjkb/nix-gen-luarc-json";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
# Add bleeding-edge plugins here.
# They can be updated with `nix flake update` (make sure to commit the generated flake.lock)
hlargs-nvim = {
url = "github:m-demare/hlargs.nvim";
flake = false;
};
nvim-yati = {
url = "github:yioneko/nvim-yati";
flake = false;
};
yaml-nvim = {
url = "github:cuducos/yaml.nvim";
flake = false;
};
cmp-diag-codes = {
url = "github:JMarkin/cmp-diag-codes";
flake = false;
};
};
outputs =
inputs @ { self
, nixpkgs
, flake-utils
, rust-overlay
, ...
}:
let
systems = builtins.attrNames nixpkgs.legacyPackages;
# This is where the Neovim derivation is built.
neovim-overlay = import ./nix/neovim-overlay.nix { inherit inputs; };
in
flake-utils.lib.eachSystem systems
(system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [
(import rust-overlay)
# Import the overlay, so that the final Neovim derivation(s) can be accessed via pkgs.<nvim-pkg>
neovim-overlay
# This adds a function can be used to generate a .luarc.json
# containing the Neovim API all plugins in the workspace directory.
# The generated file can be symlinked in the devShell's shellHook.
inputs.gen-luarc.overlays.default
];
};
shell = pkgs.mkShell {
name = "nvim-devShell";
buildInputs = with pkgs; [
# Tools for Lua and Nix development, useful for editing files in this repo
lua-language-server
nixd
stylua
luajitPackages.luacheck
nvim-dev
];
shellHook = ''
# symlink the .luarc.json generated in the overlay
ln -fs ${pkgs.nvim-luarc-json} .luarc.json
# allow quick iteration of lua configs
ln -Tfns $PWD/nvim ~/.config/nvim-dev
'';
};
in
{
packages = rec {
default = nvim;
nvim = pkgs.nvim-pkg;
};
devShells = {
default = shell;
};
})
// {
# You can add this overlay to your NixOS configuration
overlays.default = neovim-overlay;
};
}

71
nix/autocomplete.nix Normal file
View file

@ -0,0 +1,71 @@
{ inputs, pkgs, mkNvimPlugin, lib, ... }:
let
version = "2025-08-28";
src = pkgs.fetchFromGitHub {
owner = "Saghen";
repo = "blink.pairs";
rev = "3cf0b660caf266992d6c62eb1f6049c483b35409";
hash = "sha256-pE5HxryAfpMLRSRddr9kqhpI9hTnHZL/qgtHU53gt6k=";
};
rustPlatform = pkgs.makeRustPlatform {
cargo = pkgs.rust-bin.nightly."2025-04-12".minimal;
rustc = pkgs.rust-bin.nightly."2025-04-12".minimal;
};
blink-pairs-lib = rustPlatform.buildRustPackage {
pname = "blink-pairs";
inherit version src;
cargoHash = "sha256-Cn9zRsQkBwaKbBD/JEpFMBOF6CBZTDx7fQa6Aoic4YU=";
doCheck = false;
nativeBuildInputs = [
pkgs.pkg-config
];
};
blink-pairs = pkgs.vimUtils.buildVimPlugin {
pname = "blink.pairs";
inherit version src;
preInstall =
let
ext = pkgs.stdenv.hostPlatform.extensions.sharedLibrary;
in
''
mkdir -p target/release
ln -s ${blink-pairs-lib}/lib/libblink_pairs${ext} target/release/
'';
passthru = {
updateScript = pkgs.nix-update-script {
attrPath = "vimPlugins.blink-pairs.blink-pairs-lib";
};
# needed for the update script
inherit blink-pairs-lib;
};
meta = {
description = "Rainbow highlighting and intelligent auto-pairs for Neovim";
homepage = "https://github.com/Saghen/blink.pairs";
changelog = "https://github.com/Saghen/blink.pairs/blob/${src.tag}/CHANGELOG.md";
license = lib.licenses.mit;
};
};
in
with pkgs.vimPlugins; [
blink-cmp
blink-pairs
friendly-snippets
lazydev-nvim
neogen
colorful-menu-nvim
blink-compat
cmp-nvim-tags
(mkNvimPlugin inputs.cmp-diag-codes "cmp-diag-codes")
]

19
nix/lang/default.nix Normal file
View file

@ -0,0 +1,19 @@
{ pkgs, mkNvimPlugin, inputs, ... }:
let
callPackage = (file: pkgs.callPackage file {
inherit inputs pkgs mkNvimPlugin;
});
unsorted = callPackage ./unsorted.nix;
go = callPackage ./go.nix;
lua = callPackage ./lua.nix;
rust = callPackage ./rust.nix;
nix = callPackage ./nix.nix;
sql = callPackage ./sql.nix;
python = callPackage ./python.nix;
langs = [ unsorted go lua rust nix sql python ];
in
{
plugins = builtins.concatMap (x: x.plugins) langs;
packages = builtins.concatMap (x: x.packages) langs;
}

22
nix/lang/go.nix Normal file
View file

@ -0,0 +1,22 @@
{ pkgs, ... }:
{
packages = with pkgs; [
go
golangci-lint
gopls
gotools
# gofumpt
# golines
# gomodifytags
# iferr
# impl
# ginkgo
# mockgen
# govulncheck
];
plugins = [ ];
}

22
nix/lang/lua.nix Normal file
View file

@ -0,0 +1,22 @@
{ pkgs, ... }:
{
packages = with pkgs; [
lua-language-server
stylua
];
plugins = with pkgs.vimPlugins;[
{
plugin = lazydev-nvim;
optional = true;
type = "lua";
config = /*lua*/''
require('lze').load {
'lazydev-nvim',
ft= { "lua" }
}
'';
}
];
}

10
nix/lang/nix.nix Normal file
View file

@ -0,0 +1,10 @@
{ pkgs, ... }:
{
packages = with pkgs; [
nixd
nixpkgs-fmt
];
plugins = [];
}

12
nix/lang/python.nix Normal file
View file

@ -0,0 +1,12 @@
{ pkgs, ... }:
{
packages = with pkgs; [
python313Packages.ipython
ruff
ty
];
plugins = [];
}

19
nix/lang/rust.nix Normal file
View file

@ -0,0 +1,19 @@
{ pkgs, ... }:
{
packages = with pkgs; [
rust-analyzer
cargo
graphviz
];
plugins = with pkgs.vimPlugins;[
{
plugin = rustaceanvim;
optional = false;
}
];
}

64
nix/lang/sql.nix Normal file
View file

@ -0,0 +1,64 @@
{ pkgs, ... }:
{
packages = with pkgs; [
sqlfluff
postgresql
];
plugins = with pkgs.vimPlugins;[
{
plugin = vim-dadbod;
optional = true;
type = "lua";
config = /*lua*/''
require("lze").load {
"vim-dadbod",
on_plugin = "vim-dadbod-ui",
ft= { "sql", "mssql", "plsql" }
}
'';
}
{
plugin = vim-dadbod-completion;
optional = true;
type = "lua";
config = /*lua*/''
require('lze').load {
'vim-dadbod',
on_plugin = "vim-dadbod-ui",
ft= { "sql", "mssql", "plsql" }
}
'';
}
{
plugin = vim-dadbod-ui;
optional = true;
type = "lua";
config = /*lua*/''
require('lze').load {
'vim-dadbod-ui',
cmd = { "DBUI", "DBUIToggle" },
before = function(event)
vim.g.db_ui_execute_on_save = 0
vim.g.db_ui_win_position = "right"
vim.g.db_ui_show_database_icon = 1
vim.g.db_ui_use_nerd_fonts = 1
vim.g.db_ui_env_variable_url = "DATABASE_URL"
vim.g.db_ui_use_nvim_notify = true
vim.g.db_ui_auto_execute_table_helpers = 1
autocmd("FileType", {
pattern = { "dbui" },
callback = function()
vim.keymap.set("n", "<tab>", "<Plug>(DBUI_SelectLine)", { buffer = event.buffer, silent = true })
end,
})
end,
}
'';
}
];
}

93
nix/lang/unsorted.nix Normal file
View file

@ -0,0 +1,93 @@
{ inputs, mkNvimPlugin, pkgs, ... }:
let
yaml-nvim = (mkNvimPlugin inputs.yaml-nvim "yaml.nvim");
in
{
packages = with pkgs; [
bash-language-server
yaml-language-server
# systemd-language-server
# nginx-language-server
docker-language-server
vacuum-go
taplo
vscode-langservers-extracted
biome
];
plugins = with pkgs.vimPlugins; [
{
plugin = nvim-lint;
type = "lua";
optional = true;
config = /*lua*/''
require("lze").load {
"nvim-lint",
after = function()
require("lint").linters_by_ft = vim.g.linter_by_ft
require("lint").linters.sqlfluff.args = {
"lint",
"--format=json",
"--dialect=postgres",
}
end
}
'';
}
{
plugin = conform-nvim;
type = "lua";
optional = true;
config = /*lua*/''
require("lze").load {
"conform.nvim",
cmd = { "ConformInfo" },
after = function()
require("conform").setup({
formatters_by_ft = vim.g.formatters_by_ft,
default_format_opts = {
lsp_format = "fallback",
},
-- Customize formatters
formatters = {
sqlfluff = {
prepend_args = { "--dialect", "postgres" },
},
},
})
end
}
'';
}
{
plugin = SchemaStore-nvim;
type = "lua";
optional = true;
config = /*lua*/''
require("lze").load {
"schemastore.nvim",
}
'';
}
{
plugin = yaml-nvim;
type = "lua";
optional = true;
config = /*lua*/''
require("lze").load {
"yaml.nvim",
ft = {"yaml"}
}
'';
}
];
}

233
nix/mkNeovim.nix Normal file
View file

@ -0,0 +1,233 @@
# Function for creating a Neovim derivation
{ lib
, stdenv
, sqlite
, git
, neovim-unwrapped
, # Set by the overlay to ensure we use a compatible version of `wrapNeovimUnstable`
wrapNeovimUnstable
, neovimUtils
,
}:
with lib;
{
# NVIM_APPNAME - Defaults to 'nvim' if not set.
# If set to something else, this will also rename the binary.
appName ? null
, plugins ? [ ]
, # List of plugins
# List of dev plugins (will be bootstrapped) - useful for plugin developers
# { name = <plugin-name>; url = <git-url>; }
devPlugins ? [ ]
, # Regexes for config files to ignore, relative to the nvim directory.
# e.g. [ "^plugin/neogit.lua" "^ftplugin/.*.lua" ]
ignoreConfigRegexes ? [ ]
, extraPackages ? [ ]
, # Extra runtime dependencies (e.g. ripgrep, ...)
# The below arguments can typically be left as their defaults
# Additional lua packages (not plugins), e.g. from luarocks.org.
# e.g. p: [p.jsregexp]
extraLuaPackages ? p: [ ]
, # Additional python 3 packages
extraPython3Packages ? p: [ ]
, # Build Neovim with Python 3 support?
withPython3 ? true
, # Build Neovim with Ruby support?
withRuby ? false
, # Build Neovim with NodeJS support?
withNodeJs ? false
, # Add sqlite? This is a dependency for some plugins
withSqlite ? false
, # You probably don't want to create vi or vim aliases
# if the appName is something different than "nvim"
# Add a "vi" binary to the build output as an alias?
viAlias ? appName == null || appName == "nvim"
, # Add a "vim" binary to the build output as an alias?
vimAlias ? appName == null || appName == "nvim"
, wrapRc ? true
,
}:
let
# This is the structure of a plugin definition.
# Each plugin in the `plugins` argument list can also be defined as this attrset
defaultPlugin = {
plugin = null; # e.g. nvim-lspconfig
config = null; # plugin config
# If `optional` is set to `false`, the plugin is installed in the 'start' packpath
# set to `true`, it is installed in the 'opt' packpath, and can be lazy loaded with
# ':packadd! {plugin-name}
optional = true;
runtime = { };
type = "lua";
};
externalPackages = extraPackages ++ (optionals withSqlite [ sqlite ]);
# Map all plugins to an attrset { plugin = <plugin>; config = <config>; optional = <tf>; ... }
normalizedPlugins = map
(x:
defaultPlugin
// (
if x ? plugin
then x
else { plugin = x; optional = true; type = "lua"; }
))
plugins;
# This nixpkgs util function creates an attrset
# that pkgs.wrapNeovimUnstable uses to configure the Neovim build.
neovimConfig = neovimUtils.makeNeovimConfig {
inherit extraPython3Packages withPython3 withRuby withNodeJs viAlias vimAlias;
plugins = normalizedPlugins;
};
# This uses the ignoreConfigRegexes list to filter
# the nvim directory
nvimRtpSrc =
let
src = ../nvim;
in
lib.cleanSourceWith {
inherit src;
name = "nvim-rtp-src";
filter = path: tyoe:
let
srcPrefix = toString src + "/";
relPath = lib.removePrefix srcPrefix (toString path);
in
lib.all (regex: builtins.match regex relPath == null) ignoreConfigRegexes;
};
# Split runtimepath into 3 directories:
# - lua, to be prepended to the rtp at the beginning of init.lua
# - nvim, containing plugin, ftplugin, ... subdirectories
# - after, to be sourced last in the startup initialization
# See also: https://neovim.io/doc/user/starting.html
nvimRtp = stdenv.mkDerivation {
name = "nvim-rtp";
src = nvimRtpSrc;
buildPhase = ''
mkdir -p $out/nvim
mkdir -p $out/lua
rm init.lua
'';
installPhase = ''
cp -r lua $out/lua
rm -r lua
# Copy nvim/after only if it exists
if [ -d "after" ]; then
cp -r after $out/after
rm -r after
fi
# Copy rest of nvim/ subdirectories only if they exist
if [ ! -z "$(ls -A)" ]; then
cp -r -- * $out/nvim
fi
'';
};
# The final init.lua content that we pass to the Neovim wrapper.
# It wraps the user init.lua, prepends the lua lib directory to the RTP
# and prepends the nvim and after directory to the RTP
# It also adds logic for bootstrapping dev plugins (for plugin developers)
initLua =
''
-- prepend lua directory
vim.opt.rtp:prepend('${nvimRtp}/lua')
''
# Wrap init.lua
+ (builtins.readFile ../nvim/init.lua)
# Bootstrap/load dev plugins
+ optionalString (devPlugins != [ ]) (
''
local dev_pack_path = vim.fn.stdpath('data') .. '/site/pack/dev'
local dev_plugins_dir = dev_pack_path .. '/opt'
local dev_plugin_path
''
+ strings.concatMapStringsSep
"\n"
(plugin: ''
dev_plugin_path = dev_plugins_dir .. '/${plugin.name}'
if vim.fn.empty(vim.fn.glob(dev_plugin_path)) > 0 then
vim.notify('Bootstrapping dev plugin ${plugin.name} ...', vim.log.levels.INFO)
vim.cmd('!${git}/bin/git clone ${plugin.url} ' .. dev_plugin_path)
end
vim.cmd('packadd! ${plugin.name}')
'')
devPlugins
)
# Prepend nvim and after directories to the runtimepath
# NOTE: This is done after init.lua,
# because of a bug in Neovim that can cause filetype plugins
# to be sourced prematurely, see https://github.com/neovim/neovim/issues/19008
# We prepend to ensure that user ftplugins are sourced before builtin ftplugins.
+ ''
vim.opt.rtp:prepend('${nvimRtp}/nvim')
vim.opt.rtp:prepend('${nvimRtp}/after')
'';
# Add arguments to the Neovim wrapper script
extraMakeWrapperArgs =
let
sqliteLibExt = stdenv.hostPlatform.extensions.sharedLibrary;
sqliteLibPath = "${sqlite.out}/lib/libsqlite3${sqliteLibExt}";
in
builtins.concatStringsSep " " (
# Set the NVIM_APPNAME environment variable
(optional (appName != "nvim" && appName != null && appName != "")
''--set NVIM_APPNAME "${appName}"'')
# Add external packages to the PATH
++ (optional (externalPackages != [ ])
''--prefix PATH : "${makeBinPath externalPackages}"'')
# Set the LIBSQLITE_CLIB_PATH if sqlite is enabled
++ (optional withSqlite
''--set LIBSQLITE_CLIB_PATH "${sqliteLibPath}"'')
# Set the LIBSQLITE environment variable if sqlite is enabled
++ (optional withSqlite
''--set LIBSQLITE "${sqliteLibPath}"'')
);
luaPackages = neovim-unwrapped.lua.pkgs;
resolvedExtraLuaPackages = extraLuaPackages luaPackages;
# Native Lua libraries
extraMakeWrapperLuaCArgs =
optionalString (resolvedExtraLuaPackages != [ ])
''--suffix LUA_CPATH ";" "${concatMapStringsSep ";" luaPackages.getLuaCPath resolvedExtraLuaPackages}"'';
# Lua libraries
extraMakeWrapperLuaArgs =
optionalString (resolvedExtraLuaPackages != [ ])
''--suffix LUA_PATH ";" "${concatMapStringsSep ";" luaPackages.getLuaPath resolvedExtraLuaPackages}"'';
# wrapNeovimUnstable is the nixpkgs utility function for building a Neovim derivation.
neovim-wrapped = wrapNeovimUnstable neovim-unwrapped (neovimConfig
// {
luaRcContent = initLua;
wrapperArgs =
escapeShellArgs neovimConfig.wrapperArgs
+ " "
+ extraMakeWrapperArgs
+ " "
+ extraMakeWrapperLuaCArgs
+ " "
+ extraMakeWrapperLuaArgs;
wrapRc = wrapRc;
});
isCustomAppName = appName != null && appName != "nvim";
in
neovim-wrapped.overrideAttrs (oa: {
buildPhase =
oa.buildPhase
# If a custom NVIM_APPNAME has been set, rename the `nvim` binary
+ lib.optionalString isCustomAppName ''
mv $out/bin/nvim $out/bin/${lib.escapeShellArg appName}
'';
meta.mainProgram =
if isCustomAppName
then appName
else oa.meta.mainProgram;
})

113
nix/neovim-overlay.nix Normal file
View file

@ -0,0 +1,113 @@
# This overlay, when applied to nixpkgs, adds the final neovim derivation to nixpkgs.
{ inputs }: final: prev:
with final.pkgs.lib; let
pkgs = final;
lib = final.pkgs.lib;
# Use this to create a plugin from a flake input
mkNvimPlugin = src: pname:
pkgs.vimUtils.buildVimPlugin {
inherit pname src;
version = src.lastModifiedDate;
};
# Make sure we use the pinned nixpkgs instance for wrapNeovimUnstable,
# otherwise it could have an incompatible signature when applying this overlay.
pkgs-locked = inputs.nixpkgs.legacyPackages.${pkgs.system};
# This is the helper function that builds the Neovim derivation.
mkNeovim = pkgs.callPackage ./mkNeovim.nix {
inherit (pkgs-locked) wrapNeovimUnstable neovimUtils;
};
callPackage = (file: pkgs.callPackage file {
inherit inputs pkgs mkNvimPlugin lib;
});
langs = callPackage ./lang;
# A plugin can either be a package or an attrset, such as
# { plugin = <plugin>; # the package, e.g. pkgs.vimPlugins.nvim-cmp
# config = <config>; # String; a config that will be loaded with the plugin
# # Boolean; Whether to automatically load the plugin as a 'start' plugin,
# # or as an 'opt' plugin, that can be loaded with `:packadd!`
# optional = <true|false>; # Default: false
# ...
# }
all-plugins = with pkgs.vimPlugins; [
{
plugin = lze;
optional = false;
}
{
plugin = snacks-nvim;
optional = false;
}
]
++ langs.plugins
++ (callPackage ./treesitter.nix)
++ (callPackage ./autocomplete.nix)
++ [
diffview-nvim
gitsigns-nvim
vim-fugitive
which-key-nvim
better-escape-nvim
plenary-nvim
{
plugin = mini-icons;
optional = false;
type = "lua";
config = /*lua*/''
require("mini.icons").setup()
MiniIcons.mock_nvim_web_devicons()
'';
}
{ plugin = oil-nvim; optional = false; }
];
extraPackages = langs.packages;
in
{
# This is the neovim derivation
# returned by the overlay
nvim-pkg = mkNeovim {
plugins = all-plugins;
inherit extraPackages;
};
# This is meant to be used within a devshell.
# Instead of loading the lua Neovim configuration from
# the Nix store, it is loaded from $XDG_CONFIG_HOME/nvim-dev
nvim-dev = mkNeovim {
plugins = all-plugins;
inherit extraPackages;
appName = "nvim-dev";
wrapRc = false;
};
# This can be symlinked in the devShell's shellHook
nvim-luarc-json = final.mk-luarc-json {
plugins = all-plugins;
};
# You can add as many derivations as you like.
# Use `ignoreConfigRegexes` to filter out config
# files you would not like to include.
#
# For example:
#
# nvim-pkg-no-telescope = mkNeovim {
# plugins = [];
# ignoreConfigRegexes = [
# "^plugin/telescope.lua"
# "^ftplugin/.*.lua"
# ];
# inherit extraPackages;
# };
}

109
nix/treesitter.nix Normal file
View file

@ -0,0 +1,109 @@
{ inputs, pkgs, mkNvimPlugin, ... }:
let
# nvim-treesitter = pkgs.vimPlugins.nvim-treesitter.withAllGrammars;
nvim-treesitter = pkgs.vimPlugins.nvim-treesitter.withPlugins (p: [
# languages
p.rust
p.c
p.cpp
p.cuda
p.python
p.typescript
p.javascript
p.fish
p.lua
p.html
p.htmldjango
p.css
p.bash
p.vue
p.scss
p.sql
p.markdown
p.json
p.json5
p.jsonc
p.graphql
p.commonlisp
p.latex
p.glsl
p.nix
p.go
p.gotmpl
p.helm
p.gomod
p.gosum
# conf files
p.ssh_config
p.jsdoc
p.yaml
p.toml
p.proto
p.http
p.hurl
p.make
p.cmake
p.dockerfile
p.ini
p.vim
p.vimdoc
p.passwd
p.requirements
p.hcl
p.xml
p.nginx
p.tmux
p.udev
# tools
p.markdown_inline
p.jq
p.regex
p.query
p.comment
p.rst
# git
p.gitcommit
p.git_rebase
p.gitignore
p.git_config
p.gitattributes
]);
nvim-yati = (mkNvimPlugin inputs.nvim-yati "nvim-yati").overrideAttrs
{
dependencies = [ nvim-treesitter ];
};
hlargs-nvim = (mkNvimPlugin inputs.hlargs-nvim "hlargs-nvim").overrideAttrs
{
dependencies = [ nvim-treesitter ];
};
in
[
nvim-treesitter
pkgs.vimPlugins.nvim-treesitter-context
{
plugin = nvim-yati;
type = "lua";
optional = true;
config = /*lua*/''
require('lze').load {
'nvim-yati',
on_plugin = 'nvim-treesitter',
}
'';
}
{
plugin = hlargs-nvim;
type = "lua";
optional = true;
config = /*lua*/''
require('lze').load {
'hlargs.nvim',
on_plugin = 'nvim-treesitter',
}
'';
}
]

317
nvim-nix.svg Normal file
View file

@ -0,0 +1,317 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="600"
height="71.653839"
viewBox="0 0 600.00003 71.653839"
version="1.1"
id="svg95"
sodipodi:docname="nvim-nix.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview97"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
showgrid="false"
inkscape:zoom="3.7301328"
inkscape:cx="323.71502"
inkscape:cy="-34.583219"
inkscape:window-width="3580"
inkscape:window-height="1508"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g8863" />
<title
id="title70">neovim-mark@2x</title>
<description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description>
<defs
id="defs87">
<linearGradient
inkscape:collect="always"
id="linearGradient1782">
<stop
style="stop-color:#159ce0;stop-opacity:0.80000001;"
offset="0"
id="stop1778" />
<stop
style="stop-color:#105db5;stop-opacity:0.83529413;"
offset="1"
id="stop1780" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient1774">
<stop
style="stop-color:#7bb442;stop-opacity:0.80000001;"
offset="0"
id="stop1770" />
<stop
style="stop-color:#459440;stop-opacity:0.8392157;"
offset="1"
id="stop1772" />
</linearGradient>
<linearGradient
x1="167.95833"
y1="-0.46142399"
x2="167.95833"
y2="335.45523"
id="linearGradient-1"
gradientTransform="scale(0.46142398,2.1672042)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#16B0ED"
stop-opacity="0.800235524"
offset="0%"
id="stop72" />
<stop
stop-color="#0F59B2"
stop-opacity="0.83700023"
offset="100%"
id="stop74" />
</linearGradient>
<linearGradient
x1="1118.3427"
y1="-0.46586797"
x2="1118.3427"
y2="338.68604"
id="linearGradient-2"
gradientTransform="scale(0.46586797,2.1465309)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#7DB643"
offset="0%"
id="stop77" />
<stop
stop-color="#367533"
offset="100%"
id="stop79" />
</linearGradient>
<linearGradient
x1="356.33795"
y1="0"
x2="356.33795"
y2="612.90131"
id="linearGradient-3"
gradientTransform="scale(0.84189739,1.1877932)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#88C649"
stop-opacity="0.8"
offset="0%"
id="stop82" />
<stop
stop-color="#439240"
stop-opacity="0.84"
offset="100%"
id="stop84" />
</linearGradient>
<linearGradient
x1="49.021549"
y1="-0.079835393"
x2="49.021549"
y2="97.845657"
id="linearGradient-1-2"
gradientTransform="scale(0.46153975,2.1666606)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#16B0ED"
stop-opacity="0.800235524"
offset="0%"
id="stop5136" />
<stop
stop-color="#0F59B2"
stop-opacity="0.83700023"
offset="100%"
id="stop5138" />
</linearGradient>
<linearGradient
x1="326.17365"
y1="-0.069164939"
x2="326.17365"
y2="98.851547"
id="linearGradient-2-2"
gradientTransform="scale(0.46628455,2.1446132)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#7DB643"
offset="0%"
id="stop5141" />
<stop
stop-color="#367533"
offset="100%"
id="stop5143" />
</linearGradient>
<linearGradient
x1="103.88479"
y1="-0.11508822"
x2="103.88479"
y2="178.55785"
id="linearGradient-3-8"
gradientTransform="scale(0.84203823,1.1875945)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#88C649"
stop-opacity="0.8"
offset="0%"
id="stop5146" />
<stop
stop-color="#439240"
stop-opacity="0.84"
offset="100%"
id="stop5148" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1774"
id="linearGradient1776"
x1="52.443624"
y1="-87.210322"
x2="119.70557"
y2="-87.210322"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.66190409,0,0,0.66190409,-85.433543,-23.706043)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1782"
id="linearGradient1784"
x1="44.901705"
y1="-87.250641"
x2="112.14013"
y2="-87.250641"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.66190409,0,0,0.66190409,-85.433543,-23.706043)" />
</defs>
<metadata
id="metadata14713">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>neovim-mark@2x</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
aria-label="haskell-tools.nvim"
id="text4483"
style="font-weight:bold;font-size:33.4748px;font-family:Lato;-inkscape-font-specification:'Lato Bold';fill:#1a1a1a;stroke-width:1.39478"
transform="translate(307.65719,89.970579)">
<g
id="g5925"
transform="matrix(1.6576683,0,0,1.6576683,-217.36825,0)">
<g
id="g8863"
transform="matrix(0.81614217,0,0,0.81614217,-10.014267,-7.820178)">
<g
aria-label="kickstart-nix.nvim"
id="text1840"
style="font-size:47.306px;font-family:Roboto;-inkscape-font-specification:Roboto;fill:#444444;stroke-width:1.03096"
transform="translate(2.5202188,76.281885)">
<path
d="m 33.747205,-123.78629 v 20.98021 h 1.088038 q 0.331142,0 0.614978,-0.0946 0.307489,-0.0946 0.662284,-0.44941 l 9.437547,-8.96449 q 0.23653,-0.28383 0.520366,-0.42575 0.283836,-0.16557 0.70959,-0.16557 h 1.986852 l -10.383667,9.8633 q -0.425754,0.49671 -0.922467,0.78055 0.378448,0.18922 0.638631,0.4494 0.283836,0.23653 0.544019,0.56768 l 10.904033,11.873802 H 47.58421 q -0.331142,0 -0.614978,-0.09461 -0.260183,-0.118265 -0.496713,-0.449407 l -9.886954,-10.596545 q -0.189224,-0.21288 -0.378448,-0.3548 -0.165571,-0.14191 -0.354795,-0.21287 -0.189224,-0.0946 -0.449407,-0.11827 -0.23653,-0.0473 -0.591325,-0.0473 h -1.064385 v 11.873804 h -2.270688 v -34.415114 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2262" />
<path
d="m 56.501384,-112.90591 v 23.534732 h -2.247035 v -23.534732 z m 0.969773,-8.11298 q 0,0.42575 -0.189224,0.8042 -0.165571,0.3548 -0.449407,0.63863 -0.283836,0.28384 -0.662284,0.44941 -0.378448,0.16557 -0.804202,0.16557 -0.425754,0 -0.804202,-0.16557 -0.378448,-0.16557 -0.662284,-0.44941 -0.283836,-0.28383 -0.449407,-0.63863 -0.165571,-0.37845 -0.165571,-0.8042 0,-0.42576 0.165571,-0.8042 0.165571,-0.4021 0.449407,-0.68594 0.283836,-0.28384 0.662284,-0.44941 0.378448,-0.16557 0.804202,-0.16557 0.425754,0 0.804202,0.16557 0.378448,0.16557 0.662284,0.44941 0.283836,0.28384 0.449407,0.68594 0.189224,0.37844 0.189224,0.8042 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2264" />
<path
d="m 80.343603,-109.76006 q -0.118265,0.11826 -0.23653,0.21287 -0.09461,0.071 -0.283836,0.071 -0.23653,0 -0.638631,-0.30749 -0.402101,-0.33114 -1.088038,-0.70959 -0.685937,-0.37844 -1.726669,-0.68593 -1.017079,-0.33115 -2.483565,-0.33115 -2.034158,0 -3.618909,0.73325 -1.561098,0.70959 -2.649136,2.05781 -1.088038,1.34822 -1.65571,3.26411 -0.544019,1.9159 -0.544019,4.30485 0,2.483563 0.567672,4.399456 0.591325,1.915893 1.65571,3.240461 1.064385,1.300915 2.578177,1.986852 1.513792,0.685937 3.358726,0.685937 1.703016,0 2.83836,-0.402101 1.158997,-0.402101 1.89224,-0.875161 0.756896,-0.47306 1.18265,-0.875161 0.425754,-0.402101 0.70959,-0.402101 0.283836,0 0.47306,0.23653 l 0.591325,0.756896 q -0.544019,0.70959 -1.371874,1.324568 -0.827855,0.614978 -1.868587,1.064385 -1.040732,0.449407 -2.270688,0.685937 -1.206303,0.260183 -2.530871,0.260183 -2.247035,0 -4.115622,-0.804202 -1.844934,-0.827855 -3.193155,-2.3653 -1.324568,-1.561098 -2.081464,-3.808133 -0.733243,-2.247035 -0.733243,-5.109046 0,-2.69644 0.70959,-4.91983 0.70959,-2.22338 2.081464,-3.83178 1.371874,-1.60841 3.335073,-2.48357 1.986852,-0.89881 4.541376,-0.89881 2.294341,0 4.068316,0.73324 1.773975,0.73325 3.098543,1.98685 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2266" />
<path
d="m 89.095228,-123.78629 v 20.98021 h 1.088038 q 0.331142,0 0.614978,-0.0946 0.307489,-0.0946 0.662284,-0.44941 l 9.437542,-8.96449 q 0.23653,-0.28383 0.52037,-0.42575 0.28384,-0.16557 0.70959,-0.16557 h 1.98685 l -10.383664,9.8633 q -0.425754,0.49671 -0.922467,0.78055 0.378448,0.18922 0.638631,0.4494 0.283836,0.23653 0.544019,0.56768 l 10.904031,11.873802 h -1.9632 q -0.33114,0 -0.61498,-0.09461 -0.26018,-0.118265 -0.49671,-0.449407 l -9.886952,-10.596545 q -0.189224,-0.21288 -0.378448,-0.3548 -0.165571,-0.14191 -0.354795,-0.21287 -0.189224,-0.0946 -0.449407,-0.11827 -0.23653,-0.0473 -0.591325,-0.0473 h -1.064385 v 11.873804 H 86.82454 v -34.415114 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2268" />
<path
d="m 122.28039,-109.99659 q -0.18923,0.33114 -0.54402,0.33114 -0.26019,0 -0.66229,-0.28384 -0.4021,-0.30749 -1.08804,-0.66228 -0.66228,-0.37845 -1.65571,-0.66229 -0.99342,-0.30748 -2.4126,-0.30748 -1.27726,0 -2.34165,0.37844 -1.04073,0.3548 -1.79763,0.96978 -0.73324,0.61497 -1.13534,1.44283 -0.4021,0.8042 -0.4021,1.70302 0,1.11169 0.56767,1.84493 0.56767,0.73324 1.46649,1.25361 0.92246,0.52036 2.10511,0.89881 1.18265,0.37845 2.38896,0.7569 1.22995,0.37845 2.4126,0.85151 1.18265,0.4494 2.08147,1.13534 0.92246,0.685937 1.49014,1.679363 0.56767,0.993426 0.56767,2.412606 0,1.537445 -0.54402,2.862013 -0.54402,1.324568 -1.60841,2.294341 -1.04073,0.969773 -2.57817,1.537445 -1.53745,0.567672 -3.5243,0.567672 -2.48356,0 -4.28119,-0.780549 -1.79763,-0.804202 -3.21681,-2.081464 l 0.52037,-0.804202 q 0.11826,-0.189224 0.26018,-0.283836 0.16557,-0.09461 0.42575,-0.09461 0.30749,0 0.73325,0.378448 0.4494,0.378448 1.18265,0.827855 0.73324,0.425754 1.79762,0.804202 1.08804,0.378448 2.67279,0.378448 1.49014,0 2.62549,-0.402101 1.13534,-0.425754 1.89224,-1.135344 0.75689,-0.70959 1.13534,-1.65571 0.4021,-0.969773 0.4021,-2.034158 0,-1.18265 -0.56767,-1.963199 -0.56767,-0.780549 -1.49014,-1.324568 -0.92247,-0.544019 -2.10512,-0.922472 -1.15899,-0.37844 -2.38895,-0.75689 -1.22996,-0.37845 -2.41261,-0.82786 -1.15899,-0.4494 -2.08146,-1.13534 -0.92247,-0.68594 -1.49014,-1.65571 -0.56767,-0.99343 -0.56767,-2.45991 0,-1.25361 0.54402,-2.41261 0.54402,-1.159 1.53744,-2.03416 1.01708,-0.87516 2.45991,-1.39552 1.44284,-0.52037 3.24047,-0.52037 2.15242,0 3.80813,0.61498 1.67936,0.61498 3.05124,1.89224 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2270" />
<path
d="m 135.88082,-88.99273 q -2.38895,0 -3.73717,-1.324568 -1.32457,-1.324568 -1.32457,-4.091969 v -16.084043 h -3.38238 q -0.26018,0 -0.42575,-0.14191 -0.16557,-0.14192 -0.16557,-0.40211 v -0.87516 l 4.02101,-0.28383 0.56767,-8.42047 q 0.0473,-0.21288 0.18922,-0.37845 0.14192,-0.16557 0.4021,-0.16557 h 1.06439 v 8.98814 h 7.42704 v 1.67936 h -7.42704 v 15.965778 q 0,0.969773 0.23653,1.679363 0.26018,0.685937 0.68593,1.135344 0.44941,0.449407 1.04074,0.662284 0.59132,0.212877 1.27726,0.212877 0.85151,0 1.46648,-0.23653 0.61498,-0.260183 1.06439,-0.544019 0.44941,-0.307489 0.73324,-0.544019 0.28384,-0.260183 0.44941,-0.260183 0.18922,0 0.37845,0.23653 l 0.61498,0.993426 q -0.89882,0.993426 -2.29435,1.608404 -1.37187,0.591325 -2.86201,0.591325 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2272" />
<path
d="m 158.82426,-100.74827 q -3.35873,0.11826 -5.79499,0.54402 -2.4126,0.402099 -3.99735,1.111689 -1.5611,0.70959 -2.318,1.703016 -0.75689,0.969773 -0.75689,2.223382 0,1.18265 0.37844,2.057811 0.4021,0.851508 1.04074,1.41918 0.66228,0.544019 1.51379,0.804202 0.85151,0.260183 1.77397,0.260183 1.37188,0 2.50722,-0.283836 1.159,-0.307489 2.12877,-0.827855 0.99343,-0.544019 1.84493,-1.277262 0.85151,-0.733243 1.67937,-1.584751 z m -13.83701,-8.82257 q 1.84494,-1.84493 3.87909,-2.79105 2.03416,-0.94612 4.61234,-0.94612 1.89224,0 3.31142,0.61497 1.41918,0.59133 2.34165,1.72667 0.94612,1.11169 1.41918,2.7201 0.47306,1.58475 0.47306,3.54795 v 15.327142 h -0.89882 q -0.70959,0 -0.87516,-0.662284 l -0.33114,-3.027584 q -0.96977,0.94612 -1.93955,1.703016 -0.94612,0.756896 -1.98685,1.277262 -1.04073,0.520366 -2.24703,0.804202 -1.20631,0.283836 -2.64914,0.283836 -1.2063,0 -2.34165,-0.354795 -1.13534,-0.354795 -2.03415,-1.088038 -0.87517,-0.733243 -1.41918,-1.868587 -0.52037,-1.158997 -0.52037,-2.767401 0,-1.490139 0.85151,-2.767401 0.85151,-1.277262 2.67279,-2.223378 1.82128,-0.94612 4.65964,-1.5138 2.86201,-0.56767 6.85937,-0.66228 v -2.45991 q 0,-3.26412 -1.41918,-5.01444 -1.39553,-1.77397 -4.16293,-1.77397 -1.70302,0 -2.90932,0.47306 -1.18265,0.47306 -2.0105,1.04073 -0.82786,0.56767 -1.34823,1.04073 -0.52036,0.47306 -0.87516,0.47306 -0.26018,0 -0.42575,-0.11826 -0.16557,-0.11827 -0.28384,-0.30749 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2274" />
<path
d="m 170.69803,-107.22919 q 0.54402,-1.44284 1.22996,-2.55453 0.70959,-1.13534 1.6084,-1.91589 0.92247,-0.78055 2.03416,-1.18265 1.13534,-0.42575 2.50722,-0.42575 0.73324,0 1.44283,0.14191 0.70959,0.11827 1.25361,0.44941 l -0.18922,1.5611 q -0.11827,0.37845 -0.44941,0.37845 -0.28384,0 -0.87516,-0.16557 -0.56767,-0.16557 -1.51379,-0.16557 -1.37188,0 -2.43626,0.42575 -1.04073,0.4021 -1.89224,1.22996 -0.82786,0.82785 -1.46649,2.05781 -0.61498,1.2063 -1.13534,2.79105 v 15.232532 h -2.27069 v -23.534732 h 1.2063 q 0.4021,0 0.56767,0.16557 0.16558,0.16557 0.21288,0.56767 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2276" />
<path
d="m 191.70191,-88.99273 q -2.38895,0 -3.73717,-1.324568 -1.32457,-1.324568 -1.32457,-4.091969 v -16.084043 h -3.38238 q -0.26018,0 -0.42575,-0.14191 -0.16557,-0.14192 -0.16557,-0.40211 v -0.87516 l 4.02101,-0.28383 0.56767,-8.42047 q 0.0473,-0.21288 0.18922,-0.37845 0.14192,-0.16557 0.4021,-0.16557 h 1.06439 v 8.98814 h 7.42704 v 1.67936 h -7.42704 v 15.965778 q 0,0.969773 0.23653,1.679363 0.26018,0.685937 0.68593,1.135344 0.44941,0.449407 1.04074,0.662284 0.59132,0.212877 1.27726,0.212877 0.85151,0 1.46648,-0.23653 0.61498,-0.260183 1.06439,-0.544019 0.44941,-0.307489 0.73324,-0.544019 0.28384,-0.260183 0.44941,-0.260183 0.18922,0 0.37845,0.23653 l 0.61498,0.993426 q -0.89882,0.993426 -2.29435,1.608404 -1.37187,0.591325 -2.86201,0.591325 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2278" />
<path
d="m 200.85565,-104.36718 h 10.99864 v 1.91589 h -10.99864 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2280" />
<path
d="m 221.12632,-108.79029 q 1.63205,-2.03416 3.76082,-3.26411 2.15243,-1.22996 4.77791,-1.22996 1.93954,0 3.40603,0.61498 1.49014,0.61498 2.45991,1.77397 0.96978,1.159 1.46649,2.79106 0.49671,1.63205 0.49671,3.68986 v 15.043312 h -2.27069 v -15.043312 q 0,-3.31142 -1.51379,-5.18 -1.51379,-1.89224 -4.61233,-1.89224 -2.29434,0 -4.30485,1.18265 -1.98685,1.15899 -3.54795,3.24046 v 17.692442 h -2.27069 v -23.534732 h 1.25361 q 0.59133,0 0.68594,0.59132 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2282" />
<path
d="m 247.49938,-112.90591 v 23.534732 h -2.24704 v -23.534732 z m 0.96977,-8.11298 q 0,0.42575 -0.18923,0.8042 -0.16557,0.3548 -0.4494,0.63863 -0.28384,0.28384 -0.66229,0.44941 -0.37844,0.16557 -0.8042,0.16557 -0.42575,0 -0.8042,-0.16557 -0.37845,-0.16557 -0.66228,-0.44941 -0.28384,-0.28383 -0.44941,-0.63863 -0.16557,-0.37845 -0.16557,-0.8042 0,-0.42576 0.16557,-0.8042 0.16557,-0.4021 0.44941,-0.68594 0.28383,-0.28384 0.66228,-0.44941 0.37845,-0.16557 0.8042,-0.16557 0.42576,0 0.8042,0.16557 0.37845,0.16557 0.66229,0.44941 0.28383,0.28384 0.4494,0.68594 0.18923,0.37844 0.18923,0.8042 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2284" />
<path
d="M 272.78442,-89.371178 H 270.632 q -0.33114,0 -0.52037,-0.189224 -0.18922,-0.212877 -0.30749,-0.402101 l -7.1432,-10.430977 q -0.0946,0.425758 -0.3548,0.827859 l -6.81206,9.603118 q -0.16557,0.212877 -0.3548,0.402101 -0.16557,0.189224 -0.4494,0.189224 h -2.03416 l 8.56238,-12.039372 -8.23124,-11.49536 h 2.15242 q 0.33115,0 0.49672,0.14192 0.16557,0.14191 0.28383,0.33114 l 6.90668,9.95791 q 0.0473,-0.18922 0.14192,-0.4021 0.11826,-0.21288 0.23653,-0.42575 l 6.45727,-9.10641 q 0.14191,-0.21288 0.30748,-0.35479 0.16558,-0.14192 0.42576,-0.14192 h 2.05781 l -8.20759,11.35344 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2286" />
<path
d="m 277.16022,-91.192459 q 0,-0.449407 0.16557,-0.851508 0.16557,-0.402101 0.44941,-0.685937 0.30749,-0.307489 0.68594,-0.47306 0.4021,-0.189224 0.87516,-0.189224 0.4494,0 0.8515,0.189224 0.40211,0.165571 0.68594,0.47306 0.30749,0.283836 0.47306,0.685937 0.18923,0.402101 0.18923,0.851508 0,0.47306 -0.18923,0.875161 -0.16557,0.378448 -0.47306,0.685937 -0.28383,0.283836 -0.68594,0.449407 -0.4021,0.165571 -0.8515,0.165571 -0.92247,0 -1.5611,-0.614978 -0.61498,-0.638631 -0.61498,-1.561098 z"
style="font-weight:300;font-family:Lato;-inkscape-font-specification:'Lato Light'"
id="path2288" />
<path
d="m 293.22059,-110.65888 q 0.73324,-0.73324 1.53744,-1.34822 0.82786,-0.63863 1.72667,-1.06438 0.92247,-0.44941 1.9632,-0.68594 1.04073,-0.26018 2.27069,-0.26018 1.98685,0 3.52429,0.68593 1.53745,0.66229 2.55453,1.89224 1.04073,1.20631 1.5611,2.90932 0.54401,1.67937 0.54401,3.71352 v 15.445412 h -5.84229 v -15.445412 q 0,-2.22338 -1.01708,-3.42968 -1.01707,-1.22996 -3.09854,-1.22996 -1.51379,0 -2.83836,0.68594 -1.32457,0.68594 -2.50722,1.86859 v 17.550522 h -5.84229 v -24.267982 h 3.57161 q 1.13534,0 1.49013,1.06439 z"
style="font-family:Lato;-inkscape-font-specification:'Lato Bold'"
id="path2290" />
<path
d="m 335.77233,-113.63916 -9.62677,24.267982 h -5.29827 l -9.62677,-24.267982 h 4.82521 q 0.66229,0 1.08804,0.30749 0.44941,0.30749 0.59132,0.78055 l 4.6833,12.961846 q 0.37845,1.135344 0.66228,2.223382 0.28384,1.088038 0.49672,2.176076 0.23653,-1.088038 0.52036,-2.176076 0.28384,-1.088038 0.68594,-2.223382 l 4.7779,-12.961846 q 0.16558,-0.47306 0.59133,-0.78055 0.42575,-0.30749 1.01708,-0.30749 z"
style="font-family:Lato;-inkscape-font-specification:'Lato Bold'"
id="path2292" />
<path
d="m 344.92602,-113.63916 v 24.267982 h -5.86595 v -24.267982 z m 0.8042,-7.07224 q 0,0.75689 -0.30749,1.41918 -0.30749,0.66228 -0.82786,1.15899 -0.49671,0.49672 -1.18265,0.80421 -0.68593,0.28383 -1.46648,0.28383 -0.7569,0 -1.44284,-0.28383 -0.66228,-0.30749 -1.15899,-0.80421 -0.49672,-0.49671 -0.8042,-1.15899 -0.28384,-0.66229 -0.28384,-1.41918 0,-0.78055 0.28384,-1.46649 0.30748,-0.68594 0.8042,-1.18265 0.49671,-0.49671 1.15899,-0.78055 0.68594,-0.30749 1.44284,-0.30749 0.78055,0 1.46648,0.30749 0.68594,0.28384 1.18265,0.78055 0.52037,0.49671 0.82786,1.18265 0.30749,0.68594 0.30749,1.46649 z"
style="font-family:Lato;-inkscape-font-specification:'Lato Bold'"
id="path2294" />
<path
d="m 350.88656,-89.371178 v -24.267982 h 3.57161 q 1.13534,0 1.49014,1.06439 l 0.37844,1.79763 q 0.63864,-0.70959 1.32457,-1.30092 0.70959,-0.59132 1.49014,-1.01708 0.8042,-0.42575 1.70302,-0.66228 0.92246,-0.26018 2.0105,-0.26018 2.29434,0 3.76083,1.25361 1.49014,1.22995 2.22338,3.28776 0.56767,-1.2063 1.41918,-2.05781 0.85151,-0.87516 1.86859,-1.41918 1.01708,-0.54402 2.15242,-0.8042 1.159,-0.26018 2.318,-0.26018 2.0105,0 3.5716,0.61497 1.5611,0.61498 2.62548,1.79763 1.06439,1.18265 1.60841,2.88567 0.56767,1.70301 0.56767,3.90274 v 15.445412 h -5.84229 v -15.445412 q 0,-2.31799 -1.01708,-3.47699 -1.01708,-1.18265 -2.98028,-1.18265 -0.89881,0 -1.67936,0.30749 -0.7569,0.30749 -1.34822,0.89882 -0.56768,0.56767 -0.89882,1.44283 -0.33114,0.87516 -0.33114,2.0105 v 15.445412 h -5.86594 v -15.445412 q 0,-2.43626 -0.99343,-3.54795 -0.96977,-1.11169 -2.86201,-1.11169 -1.27727,0 -2.38896,0.63863 -1.08803,0.61498 -2.03415,1.70302 v 17.763402 z"
style="font-family:Lato;-inkscape-font-specification:'Lato Bold'"
id="path2296" />
</g>
</g>
<g
id="g2301"
transform="translate(6.7950945,48.768295)">
<path
fill="#7ebae4"
d="m -36.254318,-89.55896 -12.061602,21.02585 -2.815852,-4.804756 3.250288,-5.631303 -6.455455,-0.01677 -1.375982,-2.40098 1.40513,-2.455691 9.189052,0.0292 3.302196,-5.73073 z m 0.925574,16.808062 24.121211,0.0012 -2.726012,4.857064 -6.470627,-0.01797 3.213152,5.636095 -1.377581,2.399783 -2.81505,0.0032 -4.569969,-8.024697 -6.581633,-0.01358 z m 14.039327,-9.213408 -12.059606,-21.027044 5.54226,-0.0523 3.219541,5.64927 3.242303,-5.61892 2.753959,6.6e-4 1.410325,2.45289 -4.619884,7.99555 3.279436,5.7443 z"
clip-rule="evenodd"
fill-rule="evenodd"
id="path830"
style="fill:url(#linearGradient1784);fill-opacity:1;stroke-width:0.556933" />
<path
fill="#5277c3"
d="m -40.607068,-80.897381 12.059606,21.027048 -5.54226,0.05231 -3.219542,-5.649272 -3.242302,5.618926 -2.75396,-7.95e-4 -1.410321,-2.452889 4.619881,-7.995549 -3.279437,-5.744305 z m 14.007383,-9.266509 -24.121209,-0.001 2.726409,-4.85667 6.470229,0.0179 -3.213153,-5.63609 1.377579,-2.39979 2.815452,-0.004 4.569569,8.0247 6.582033,0.0136 2.793491,4.84109 z m 0.941147,16.85677 12.061604,-21.02625 2.815853,4.80516 -3.25069,5.6309 6.455855,0.0172 1.375979,2.400982 -1.40513,2.455684 -9.189049,-0.02915 -3.302197,5.730729 z"
clip-rule="evenodd"
fill-rule="evenodd"
id="path832"
sodipodi:nodetypes="ccccccccccccccccccccccccccccccc"
style="fill:url(#linearGradient1776);fill-opacity:1;stroke-width:0.556933" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -0,0 +1,4 @@
setl expandtab
setl shiftwidth=2
setl softtabstop=2
setl tabstop=2

View file

@ -0,0 +1 @@
vim.bo.syntax = "htmldjango"

View file

@ -0,0 +1,7 @@
setl autoindent
setl conceallevel=0
setl expandtab
setl formatoptions=tcq2l
setl shiftwidth=2
setl softtabstop=2
setl tabstop=2

View file

@ -0,0 +1 @@
vim.b.indentkeys = "0{,0},0),0],0#,!^F,o,O,e"

View file

@ -0,0 +1,2 @@
vim.bo.syntax = "snippets"
vim.bo.omnifunc = "syntaxcomplete#Complete"

View file

@ -0,0 +1,8 @@
; extends
((subject) @injection.content
(#set! injection.language "markdown_inline"))
((message_line) @injection.content
(#set! injection.language "markdown")
(#set! injection.combined))

View file

@ -0,0 +1,23 @@
;extends
; python
(element
(start_tag
(attribute
(quoted_attribute_value
((attribute_value) @_idd (#eq? @_idd "python")))))
((text) @injection.content (#set! injection.language "python")))
; lua
(element
(start_tag
(attribute
(quoted_attribute_value
((attribute_value) @_idd (#eq? @_idd "lua")))))
((text) @injection.content (#set! injection.language "lua")))

View file

@ -0,0 +1,6 @@
; extends
((identifier) @variable.builtin
(#any-of? @variable.builtin "vim" "bit")
(#set! "priority" 128))

View file

@ -0,0 +1,41 @@
; inherits: quote
; Don't use `return` statements for function matching in Lua.
; Allow `for` and `while` keywords to be jumpable.
(for_statement
[
"for"
"do"
] @open.loop
"end" @close.loop) @scope.loop
(while_statement
[
"while"
"do"
] @open.loop
"end" @close.loop) @scope.loop
(break_statement) @mid.loop.1
(if_statement
"if" @open.if
"end" @close.if) @scope.if
(else_statement
"else" @mid.if.1)
(elseif_statement
"elseif" @mid.if.2)
(function_declaration
"function" @open.function
"end" @close.function) @scope.function
(function_definition
"function" @open.function
"end" @close.function) @scope.function
(do_statement
"do" @open.block
"end" @close.block) @scope.block

View file

@ -0,0 +1,98 @@
;extends
; sql
(
call
function: (attribute attribute: (identifier) @id (#match? @id "execute|read_sql|text|fetch|prepare|fetchrow"))
arguments: (argument_list
(string (string_content) @injection.content (#set! injection.language "sql"))
)
)
; (
; call
; function: (attribute attribute: (identifier) @id (#match? @id "execute|read_sql|text"))
; arguments: (argument_list
; (
; concatenated_string
; (string (string_content) @injection.content (#set! injection.language "sql"))
; )
; )
; )
(
call
function: ((identifier) @id (#match? @id "text"))
arguments: (argument_list
(string (string_content) @injection.content (#set! injection.language "sql"))
)
)
(
call
function: ((identifier) @id (#match? @id "text"))
arguments: (argument_list
(
concatenated_string
(string (string_content) @injection.content (#set! injection.language "sql"))
)
)
)
(assignment
((identifier) @_varx (#match? @_varx ".*sql$"))
(string
(string_content) @injection.content (#set! injection.language "sql")))
;lua
(assignment
((identifier) @_varx (#match? @_varx ".*lua$"))
(string
(string_content) @injection.content (#set! injection.language "lua")))
; rst
(
function_definition
(block
(expression_statement
(string
(string_content) @injection.content (#set! injection.language "rst"))))
)
; js
(
assignment
((identifier) @_varx (#match? @_varx ".*js$"))
(string
(string_content) @injection.content (#set! injection.language "javascript"))
)
; css
(assignment
((identifier) @_varx (#match? @_varx ".*html$"))
(string
(string_content) @injection.content (#set! injection.language "html")))
; css
(assignment
((identifier) @_varx (#match? @_varx ".*css$"))
(string
(string_content) @injection.content (#set! injection.language "css")))
(call
function: (attribute
attribute: (identifier) @_idd (#eq? @_idd "style"))
arguments: (argument_list
(string (string_content) @injection.content (#set! injection.language "css"))))
; json
(call
function: (attribute
attribute: (identifier) @_idd (#eq? @_idd "loads"))
arguments: (argument_list
(string (string_content) @injection.content (#set! injection.language "json") ) ) )
(assignment
((identifier) @_varx (#match? @_varx ".*json$"))
(string
(string_content) @injection.content (#set! injection.language "json")))

View file

@ -0,0 +1,376 @@
-- This file is generated by ex-colors. The credit goes to the authors and contributors of the original colorscheme bamboo-light.
vim.api.nvim_set_var("colors_name", "ex-bamboo-light")
vim.api.nvim_set_var("terminal_color_0", "#fff8f0")
vim.api.nvim_set_var("terminal_color_1", "#c72a3c")
vim.api.nvim_set_var("terminal_color_2", "#27850b")
vim.api.nvim_set_var("terminal_color_3", "#a77b00")
vim.api.nvim_set_var("terminal_color_4", "#1745d5")
vim.api.nvim_set_var("terminal_color_5", "#8a4adf")
vim.api.nvim_set_var("terminal_color_6", "#188a9e")
vim.api.nvim_set_var("terminal_color_7", "#3a4238")
vim.api.nvim_set_var("terminal_color_8", "#a1a7a0")
vim.api.nvim_set_var("terminal_color_9", "#c72a3c")
vim.api.nvim_set_var("terminal_color_10", "#27850b")
vim.api.nvim_set_var("terminal_color_11", "#a77b00")
vim.api.nvim_set_var("terminal_color_12", "#1745d5")
vim.api.nvim_set_var("terminal_color_13", "#8a4adf")
vim.api.nvim_set_var("terminal_color_14", "#188a9e")
vim.api.nvim_set_var("terminal_color_15", "#3a4238")
vim.api.nvim_set_option_value("background", "light", {})
vim.api.nvim_set_hl(0, "@attribute", { fg = 1608350 })
vim.api.nvim_set_hl(0, "@character.special", { link = "Special" })
vim.api.nvim_set_hl(0, "@comment", { cterm = { italic = true }, fg = 7293957, italic = true })
vim.api.nvim_set_hl(0, "@comment.error", { bg = 13052476, bold = true, cterm = { bold = true }, fg = 16775408 })
vim.api.nvim_set_hl(0, "@comment.note", { bg = 1525205, bold = true, cterm = { bold = true }, fg = 16775408 })
vim.api.nvim_set_hl(0, "@comment.warning", { bg = 14637350, bold = true, cterm = { bold = true }, fg = 16775408 })
vim.api.nvim_set_hl(0, "@constant.builtin", { link = "Constant" })
vim.api.nvim_set_hl(0, "@constant.macro", { link = "Macro" })
vim.api.nvim_set_hl(0, "@constructor", { bold = true, cterm = { bold = true }, fg = 10976000 })
vim.api.nvim_set_hl(0, "@diff.delta", { link = "DiffChange" })
vim.api.nvim_set_hl(0, "@diff.minus", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "@diff.plus", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "@function.builtin", { bold = true, cterm = { bold = true }, fg = 14637350 })
vim.api.nvim_set_hl(0, "@function.call", { link = "Function" })
vim.api.nvim_set_hl(0, "@function.macro", { bold = true, cterm = { bold = true }, fg = 13111504 })
vim.api.nvim_set_hl(0, "@function.method", { link = "Function" })
vim.api.nvim_set_hl(0, "@function.method.call", { link = "Function" })
vim.api.nvim_set_hl(0, "@keyword.conditional", { link = "Conditional" })
vim.api.nvim_set_hl(0, "@keyword.conditional.ternary", { link = "Operator" })
vim.api.nvim_set_hl(0, "@keyword.coroutine", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@keyword.debug", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@keyword.directive", { link = "PreProc" })
vim.api.nvim_set_hl(0, "@keyword.directive.define", { bold = true, cterm = { bold = true }, fg = 9063135 })
vim.api.nvim_set_hl(0, "@keyword.exception", { link = "Exception" })
vim.api.nvim_set_hl(0, "@keyword.import", { link = "Include" })
vim.api.nvim_set_hl(0, "@keyword.modifier", { cterm = { italic = true }, fg = 9063135, italic = true })
vim.api.nvim_set_hl(0, "@keyword.operator", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@keyword.repeat", { link = "Repeat" })
vim.api.nvim_set_hl(0, "@keyword.return", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@keyword.type", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@lsp.mod.readonly", { link = "@constant" })
vim.api.nvim_set_hl(0, "@lsp.type.event", { link = "Label" })
vim.api.nvim_set_hl(0, "@lsp.type.macro", { link = "Macro" })
vim.api.nvim_set_hl(0, "@lsp.type.typeParameter", { link = "@type" })
vim.api.nvim_set_hl(0, "@markup.heading", { link = "htmlTitle" })
vim.api.nvim_set_hl(0, "@markup.heading.1", { link = "markdownH1" })
vim.api.nvim_set_hl(0, "@markup.heading.2", { link = "markdownH2" })
vim.api.nvim_set_hl(0, "@markup.heading.3", { link = "markdownH3" })
vim.api.nvim_set_hl(0, "@markup.heading.4", { link = "markdownH4" })
vim.api.nvim_set_hl(0, "@markup.heading.5", { link = "markdownH5" })
vim.api.nvim_set_hl(0, "@markup.heading.6", { link = "markdownH6" })
vim.api.nvim_set_hl(0, "@markup.italic", { link = "markdownItalic" })
vim.api.nvim_set_hl(0, "@markup.link", { link = "Tag" })
vim.api.nvim_set_hl(0, "@markup.link.label", { link = "markdownLinkText" })
vim.api.nvim_set_hl(0, "@markup.link.url", { link = "markdownUrl" })
vim.api.nvim_set_hl(0, "@markup.list", { link = "markdownListMarker" })
vim.api.nvim_set_hl(0, "@markup.list.checked", { bold = true, cterm = { bold = true }, fg = 10976000 })
vim.api.nvim_set_hl(0, "@markup.list.unchecked", { bold = true, cterm = { bold = true }, fg = 8619905 })
vim.api.nvim_set_hl(0, "@markup.math", { fg = 1540095 })
vim.api.nvim_set_hl(0, "@markup.quote", { fg = 8619905 })
vim.api.nvim_set_hl(0, "@markup.raw", { link = "markdownCode" })
vim.api.nvim_set_hl(0, "@markup.raw.block", { link = "markdownCodeBlock" })
vim.api.nvim_set_hl(0, "@markup.strikethrough", { link = "markdownStrike" })
vim.api.nvim_set_hl(0, "@markup.strong", { link = "markdownBold" })
vim.api.nvim_set_hl(0, "@markup.underline", { link = "htmlUnderline" })
vim.api.nvim_set_hl(0, "@module", { cterm = { italic = true }, fg = 1540095, italic = true })
vim.api.nvim_set_hl(0, "@module.builtin", { link = "@variable.builtin" })
vim.api.nvim_set_hl(0, "@property", { link = "@variable.member" })
vim.api.nvim_set_hl(0, "@punctuation.bracket", { link = "Delimiter" })
vim.api.nvim_set_hl(0, "@punctuation.delimiter", { link = "Delimiter" })
vim.api.nvim_set_hl(0, "@string.documentation", { fg = 1926152 })
vim.api.nvim_set_hl(0, "@string.escape", { fg = 12603472 })
vim.api.nvim_set_hl(0, "@string.regexp", { link = "Constant" })
vim.api.nvim_set_hl(0, "@string.special", { link = "Special" })
vim.api.nvim_set_hl(0, "@string.special.path", { cterm = { underline = true }, fg = 1540095, underline = true })
vim.api.nvim_set_hl(0, "@string.special.symbol", { link = "@variable.member" })
vim.api.nvim_set_hl(
0,
"@string.special.url",
{ cterm = { italic = true, underline = true }, fg = 1608350, italic = true, underline = true }
)
vim.api.nvim_set_hl(0, "@tag", { fg = 9063135 })
vim.api.nvim_set_hl(0, "@tag.attribute", { link = "@variable.member" })
vim.api.nvim_set_hl(0, "@tag.builtin", { link = "@tag" })
vim.api.nvim_set_hl(0, "@tag.delimiter", { link = "Delimiter" })
vim.api.nvim_set_hl(0, "@type.builtin", { link = "Type" })
vim.api.nvim_set_hl(0, "@type.definition", { link = "Type" })
vim.api.nvim_set_hl(0, "@variable", { fg = 3818040 })
vim.api.nvim_set_hl(0, "@variable.builtin", { fg = 13052476 })
vim.api.nvim_set_hl(0, "@variable.member", { fg = 1608350 })
vim.api.nvim_set_hl(0, "@variable.parameter", { cterm = { italic = true }, fg = 12603472, italic = true })
vim.api.nvim_set_hl(0, "@variable.parameter.builtin", { cterm = { italic = true }, fg = 13052476, italic = true })
vim.api.nvim_set_hl(0, "Added", { ctermfg = 2, fg = 21795 })
vim.api.nvim_set_hl(0, "BlinkCmpCursorLineMenuHack", { bg = 14342850 })
vim.api.nvim_set_hl(0, "BlinkCmpDoc", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpDocBorder", { link = "FloatBorder" })
vim.api.nvim_set_hl(0, "BlinkCmpDocCursorLine", { link = "Visual" })
vim.api.nvim_set_hl(0, "BlinkCmpDocSeparator", { link = "NormalFloat" })
vim.api.nvim_set_hl(
0,
"BlinkCmpGhostText",
{ bg = 16448224, cterm = { italic = true, nocombine = true }, fg = 8619905, italic = true, nocombine = true }
)
vim.api.nvim_set_hl(0, "BlinkCmpKind", { fg = 9063135 })
vim.api.nvim_set_hl(0, "BlinkCmpKindArray", { fg = 10976000 })
vim.api.nvim_set_hl(0, "BlinkCmpKindBoolean", { fg = 14637350 })
vim.api.nvim_set_hl(0, "BlinkCmpKindClass", { fg = 10976000 })
vim.api.nvim_set_hl(0, "BlinkCmpKindCodeium", { fg = 3818040 })
vim.api.nvim_set_hl(0, "BlinkCmpKindColor", { fg = 2589963 })
vim.api.nvim_set_hl(0, "BlinkCmpKindConstant", { fg = 14637350 })
vim.api.nvim_set_hl(0, "BlinkCmpKindConstructor", { fg = 1525205 })
vim.api.nvim_set_hl(0, "BlinkCmpKindCopilot", { fg = 3818040 })
vim.api.nvim_set_hl(0, "BlinkCmpKindDefault", { fg = 9063135 })
vim.api.nvim_set_hl(0, "BlinkCmpKindEnum", { fg = 10976000 })
vim.api.nvim_set_hl(0, "BlinkCmpKindEnumMember", { fg = 14637350 })
vim.api.nvim_set_hl(0, "BlinkCmpKindEvent", { fg = 10976000 })
vim.api.nvim_set_hl(0, "BlinkCmpKindField", { fg = 1608350 })
vim.api.nvim_set_hl(0, "BlinkCmpKindFile", { fg = 2589963 })
vim.api.nvim_set_hl(0, "BlinkCmpKindFolder", { fg = 1540095 })
vim.api.nvim_set_hl(0, "BlinkCmpKindFunction", { fg = 1525205 })
vim.api.nvim_set_hl(0, "BlinkCmpKindInterface", { fg = 2589963 })
vim.api.nvim_set_hl(0, "BlinkCmpKindKey", { fg = 1608350 })
vim.api.nvim_set_hl(0, "BlinkCmpKindKeyword", { fg = 9063135 })
vim.api.nvim_set_hl(0, "BlinkCmpKindMethod", { fg = 1525205 })
vim.api.nvim_set_hl(0, "BlinkCmpKindModule", { fg = 1540095 })
vim.api.nvim_set_hl(0, "BlinkCmpKindNamespace", { fg = 1540095 })
vim.api.nvim_set_hl(0, "BlinkCmpKindNull", { fg = 10594208 })
vim.api.nvim_set_hl(0, "BlinkCmpKindNumber", { fg = 14637350 })
vim.api.nvim_set_hl(0, "BlinkCmpKindObject", { fg = 13052476 })
vim.api.nvim_set_hl(0, "BlinkCmpKindOperator", { fg = 7096224 })
vim.api.nvim_set_hl(0, "BlinkCmpKindPackage", { fg = 10976000 })
vim.api.nvim_set_hl(0, "BlinkCmpKindProperty", { fg = 1608350 })
vim.api.nvim_set_hl(0, "BlinkCmpKindReference", { fg = 14637350 })
vim.api.nvim_set_hl(0, "BlinkCmpKindSnippet", { cterm = { italic = true }, fg = 13111504, italic = true })
vim.api.nvim_set_hl(0, "BlinkCmpKindString", { fg = 2589963 })
vim.api.nvim_set_hl(0, "BlinkCmpKindStruct", { fg = 10976000 })
vim.api.nvim_set_hl(0, "BlinkCmpKindTabNine", { fg = 3818040 })
vim.api.nvim_set_hl(0, "BlinkCmpKindText", { fg = 8619905 })
vim.api.nvim_set_hl(0, "BlinkCmpKindTypeParameter", { fg = 12603472 })
vim.api.nvim_set_hl(0, "BlinkCmpKindUnit", { fg = 10976000 })
vim.api.nvim_set_hl(0, "BlinkCmpKindValue", { fg = 14637350 })
vim.api.nvim_set_hl(0, "BlinkCmpKindVariable", { fg = 13052476 })
vim.api.nvim_set_hl(0, "BlinkCmpLabel", { fg = 3818040 })
vim.api.nvim_set_hl(
0,
"BlinkCmpLabelDeprecated",
{ cterm = { strikethrough = true }, fg = 8619905, strikethrough = true }
)
vim.api.nvim_set_hl(0, "BlinkCmpLabelDescription", { fg = 8619905 })
vim.api.nvim_set_hl(0, "BlinkCmpLabelDetail", { link = "Comment" })
vim.api.nvim_set_hl(0, "BlinkCmpLabelMatch", { fg = 1608350 })
vim.api.nvim_set_hl(0, "BlinkCmpMenu", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpMenuBorder", { link = "FloatBorder" })
vim.api.nvim_set_hl(0, "BlinkCmpMenuSelection", { link = "PmenuSel" })
vim.api.nvim_set_hl(0, "BlinkCmpScrollBarGutter", { link = "PmenuSbar" })
vim.api.nvim_set_hl(0, "BlinkCmpScrollBarThumb", { link = "PmenuThumb" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelp", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelpActiveParameter", { link = "LspSignatureActiveParameter" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelpBorder", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpSource", { fg = 3818040 })
vim.api.nvim_set_hl(0, "Changed", { ctermfg = 6, fg = 29555 })
vim.api.nvim_set_hl(0, "ColorColumn", { bg = 13819319 })
vim.api.nvim_set_hl(0, "Comment", { cterm = { italic = true }, fg = 8619905, italic = true })
vim.api.nvim_set_hl(0, "Conceal", { fg = 8619905 })
vim.api.nvim_set_hl(0, "Conditional", { cterm = { italic = true }, fg = 9063135, italic = true })
vim.api.nvim_set_hl(0, "Constant", { fg = 14637350 })
vim.api.nvim_set_hl(0, "CurSearch", { bg = 14637350, fg = 16448224 })
vim.api.nvim_set_hl(0, "Cursor", { cterm = { reverse = true }, reverse = true })
vim.api.nvim_set_hl(0, "CursorColumn", { link = "CursorLine" })
vim.api.nvim_set_hl(0, "CursorLine", { bg = 15395536 })
vim.api.nvim_set_hl(0, "CursorLineNr", { fg = 3818040 })
vim.api.nvim_set_hl(0, "Debug", { fg = 14637350 })
vim.api.nvim_set_hl(0, "Delimiter", { fg = 8619905 })
vim.api.nvim_set_hl(0, "DiagnosticDeprecated", { link = "Strike" })
vim.api.nvim_set_hl(0, "DiagnosticError", { fg = 13052476 })
vim.api.nvim_set_hl(0, "DiagnosticHint", { fg = 9063135 })
vim.api.nvim_set_hl(0, "DiagnosticInfo", { fg = 1608350 })
vim.api.nvim_set_hl(0, "DiagnosticOk", { fg = 2589963 })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineError", { cterm = { undercurl = true }, sp = 13052476, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineHint", { cterm = { undercurl = true }, sp = 9063135, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineInfo", { cterm = { undercurl = true }, sp = 1525205, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineOk", { cterm = { undercurl = true }, sp = 2589963, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineWarn", { cterm = { undercurl = true }, sp = 10976000, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextError", { bg = 15852750, fg = 10428976 })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextHint", { bg = 15525851, fg = 7224242 })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextInfo", { bg = 14937302, fg = 1273470 })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextWarn", { bg = 15657930, fg = 8806912 })
vim.api.nvim_set_hl(0, "DiagnosticWarn", { fg = 10976000 })
vim.api.nvim_set_hl(0, "DiffAdd", { bg = 12641195 })
vim.api.nvim_set_hl(0, "DiffChange", { bg = 13819115 })
vim.api.nvim_set_hl(0, "DiffDelete", { bg = 16363445 })
vim.api.nvim_set_hl(0, "DiffText", { bg = 12766427 })
vim.api.nvim_set_hl(0, "Directory", { fg = 1525205 })
vim.api.nvim_set_hl(0, "EndOfBuffer", { fg = 16448224 })
vim.api.nvim_set_hl(0, "Error", { fg = 13052476 })
vim.api.nvim_set_hl(0, "ErrorMsg", { bold = true, cterm = { bold = true }, fg = 13052476 })
vim.api.nvim_set_hl(0, "Exception", { link = "Keyword" })
vim.api.nvim_set_hl(0, "Float", { link = "Constant" })
vim.api.nvim_set_hl(0, "FloatBorder", { bg = 14408644, fg = 9063135 })
vim.api.nvim_set_hl(0, "FloatFooter", { fg = 8619905 })
vim.api.nvim_set_hl(0, "FloatTitle", { fg = 13052476 })
vim.api.nvim_set_hl(0, "FoldColumn", { fg = 3818040 })
vim.api.nvim_set_hl(0, "Folded", { bg = 15395536, fg = 3818040 })
vim.api.nvim_set_hl(0, "Function", { bold = true, cterm = { bold = true }, fg = 1525205 })
vim.api.nvim_set_hl(0, "GitSignsAdd", { fg = 2589963 })
vim.api.nvim_set_hl(0, "GitSignsAddCul", { link = "GitSignsAdd" })
vim.api.nvim_set_hl(0, "GitSignsAddInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsAddLn", { fg = 2589963 })
vim.api.nvim_set_hl(0, "GitSignsAddLnInline", { link = "GitSignsAddInline" })
vim.api.nvim_set_hl(0, "GitSignsAddNr", { fg = 2589963 })
vim.api.nvim_set_hl(0, "GitSignsAddPreview", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "GitSignsChange", { fg = 1525205 })
vim.api.nvim_set_hl(0, "GitSignsChangeCul", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangeInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsChangeLn", { fg = 1525205 })
vim.api.nvim_set_hl(0, "GitSignsChangeLnInline", { link = "GitSignsChangeInline" })
vim.api.nvim_set_hl(0, "GitSignsChangeNr", { fg = 1525205 })
vim.api.nvim_set_hl(0, "GitSignsChangedelete", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteCul", { link = "GitSignsChangeCul" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteLn", { link = "GitSignsChangeLn" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteNr", { link = "GitSignsChangeNr" })
vim.api.nvim_set_hl(0, "GitSignsCurrentLineBlame", { link = "NonText" })
vim.api.nvim_set_hl(0, "GitSignsDelete", { fg = 13052476 })
vim.api.nvim_set_hl(0, "GitSignsDeleteCul", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsDeleteLn", { fg = 13052476 })
vim.api.nvim_set_hl(0, "GitSignsDeleteLnInline", { link = "GitSignsDeleteInline" })
vim.api.nvim_set_hl(0, "GitSignsDeleteNr", { fg = 13052476 })
vim.api.nvim_set_hl(0, "GitSignsDeletePreview", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteVirtLn", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteVirtLnInLine", { link = "GitSignsDeleteLnInline" })
vim.api.nvim_set_hl(0, "GitSignsStagedAdd", { fg = 1262085 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddCul", { fg = 1262085 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddLn", { fg = 1262085 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddNr", { fg = 1262085 })
vim.api.nvim_set_hl(0, "GitSignsStagedChange", { fg = 729706 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeCul", { fg = 729706 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeLn", { fg = 729706 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeNr", { fg = 729706 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedelete", { fg = 729706 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteCul", { fg = 729706 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteLn", { fg = 729706 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteNr", { fg = 729706 })
vim.api.nvim_set_hl(0, "GitSignsStagedDelete", { fg = 6493470 })
vim.api.nvim_set_hl(0, "GitSignsStagedDeleteCul", { fg = 6493470 })
vim.api.nvim_set_hl(0, "GitSignsStagedDeleteNr", { fg = 6493470 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdelete", { fg = 6493470 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteCul", { fg = 6493470 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteLn", { fg = 6493470 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteNr", { fg = 6493470 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntracked", { fg = 5455104 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedCul", { fg = 1262085 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedLn", { fg = 5455104 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedNr", { fg = 5455104 })
vim.api.nvim_set_hl(0, "GitSignsTopdelete", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteCul", { link = "GitSignsDeleteCul" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteLn", { link = "GitSignsDeleteLn" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteNr", { link = "GitSignsDeleteNr" })
vim.api.nvim_set_hl(0, "GitSignsUntracked", { fg = 10976000 })
vim.api.nvim_set_hl(0, "GitSignsUntrackedCul", { link = "GitSignsAddCul" })
vim.api.nvim_set_hl(0, "GitSignsUntrackedLn", { fg = 10976000 })
vim.api.nvim_set_hl(0, "GitSignsUntrackedNr", { fg = 10976000 })
vim.api.nvim_set_hl(0, "GitSignsVirtLnum", { link = "GitSignsDeleteVirtLn" })
vim.api.nvim_set_hl(0, "Identifier", { fg = 13052476 })
vim.api.nvim_set_hl(0, "Keyword", { bold = true, cterm = { bold = true }, fg = 9063135 })
vim.api.nvim_set_hl(0, "Label", { bold = true, cterm = { bold = true }, fg = 13052476 })
vim.api.nvim_set_hl(0, "LineNr", { fg = 10594208 })
vim.api.nvim_set_hl(0, "LspCodeLens", { link = "Comment" })
vim.api.nvim_set_hl(0, "LspCodeLensSeparator", { fg = 10594208 })
vim.api.nvim_set_hl(0, "LspInlayHint", { fg = 10594208 })
vim.api.nvim_set_hl(0, "LspReferenceRead", { bg = 15000780 })
vim.api.nvim_set_hl(0, "LspReferenceText", { bg = 15000780 })
vim.api.nvim_set_hl(0, "LspReferenceWrite", { bg = 15000780 })
vim.api.nvim_set_hl(0, "Macro", { fg = 13111504 })
vim.api.nvim_set_hl(0, "MatchParen", { bg = 10594208, bold = true, cterm = { bold = true }, fg = 14637350 })
vim.api.nvim_set_hl(0, "MiniStatuslineDevinfo", { bg = 15000780, fg = 3818040 })
vim.api.nvim_set_hl(0, "MiniStatuslineFileinfo", { bg = 15000780, fg = 3818040 })
vim.api.nvim_set_hl(0, "MiniStatuslineFilename", { bg = 15395536, fg = 10594208 })
vim.api.nvim_set_hl(0, "MiniStatuslineInactive", { bg = 16448224, fg = 10594208 })
vim.api.nvim_set_hl(
0,
"MiniStatuslineModeCommand",
{ bg = 10976000, bold = true, cterm = { bold = true }, fg = 16448224 }
)
vim.api.nvim_set_hl(
0,
"MiniStatuslineModeInsert",
{ bg = 1525205, bold = true, cterm = { bold = true }, fg = 16448224 }
)
vim.api.nvim_set_hl(
0,
"MiniStatuslineModeNormal",
{ bg = 2589963, bold = true, cterm = { bold = true }, fg = 16448224 }
)
vim.api.nvim_set_hl(0, "MiniStatuslineModeOther", { bg = 1608350, bold = true, cterm = { bold = true }, fg = 16448224 })
vim.api.nvim_set_hl(
0,
"MiniStatuslineModeReplace",
{ bg = 13052476, bold = true, cterm = { bold = true }, fg = 16448224 }
)
vim.api.nvim_set_hl(
0,
"MiniStatuslineModeVisual",
{ bg = 9063135, bold = true, cterm = { bold = true }, fg = 16448224 }
)
vim.api.nvim_set_hl(0, "ModeMsg", { bold = true, cterm = { bold = true }, fg = 1206391 })
vim.api.nvim_set_hl(0, "MoreMsg", { bold = true, cterm = { bold = true }, fg = 1525205 })
vim.api.nvim_set_hl(0, "NonText", { fg = 10594208 })
vim.api.nvim_set_hl(0, "Normal", { bg = 16448224, fg = 3818040 })
vim.api.nvim_set_hl(0, "NormalFloat", { bg = 14408644, fg = 3818040 })
vim.api.nvim_set_hl(0, "NormalNC", { bg = 14408644, fg = 8619905 })
vim.api.nvim_set_hl(0, "Operator", { fg = 7096224 })
vim.api.nvim_set_hl(0, "Pmenu", { bg = 15395536, fg = 3818040 })
vim.api.nvim_set_hl(0, "PmenuSbar", { bg = 15395536 })
vim.api.nvim_set_hl(0, "PmenuSel", { bg = 14342850 })
vim.api.nvim_set_hl(0, "PmenuThumb", { bg = 10594208 })
vim.api.nvim_set_hl(0, "PreProc", { fg = 9063135 })
vim.api.nvim_set_hl(0, "Question", { fg = 10976000 })
vim.api.nvim_set_hl(0, "QuickFixLine", { cterm = { underline = true }, fg = 1525205, underline = true })
vim.api.nvim_set_hl(0, "RainbowDelimiterBlue", { fg = 1127584 })
vim.api.nvim_set_hl(0, "RainbowDelimiterCyan", { fg = 1206391 })
vim.api.nvim_set_hl(0, "RainbowDelimiterGreen", { fg = 1926152 })
vim.api.nvim_set_hl(0, "RainbowDelimiterOrange", { fg = 10961693 })
vim.api.nvim_set_hl(0, "RainbowDelimiterRed", { fg = 9773101 })
vim.api.nvim_set_hl(0, "RainbowDelimiterViolet", { fg = 6830247 })
vim.api.nvim_set_hl(0, "RainbowDelimiterYellow", { fg = 8215552 })
vim.api.nvim_set_hl(0, "Removed", { ctermfg = 1, fg = 5832712 })
vim.api.nvim_set_hl(0, "Repeat", { link = "Keyword" })
vim.api.nvim_set_hl(0, "Search", { bg = 7293957, fg = 16448224 })
vim.api.nvim_set_hl(0, "SignColumn", { fg = 3818040 })
vim.api.nvim_set_hl(0, "Special", { fg = 13052476 })
vim.api.nvim_set_hl(0, "SpecialComment", { link = "Comment" })
vim.api.nvim_set_hl(0, "SpecialKey", { link = "NonText" })
vim.api.nvim_set_hl(0, "SpellBad", { cterm = { undercurl = true }, sp = 13052476, undercurl = true })
vim.api.nvim_set_hl(0, "SpellCap", { cterm = { undercurl = true }, sp = 10976000, undercurl = true })
vim.api.nvim_set_hl(0, "SpellLocal", { cterm = { undercurl = true }, sp = 1525205, undercurl = true })
vim.api.nvim_set_hl(0, "SpellRare", { cterm = { undercurl = true }, sp = 9063135, undercurl = true })
vim.api.nvim_set_hl(0, "Statement", { fg = 9063135 })
vim.api.nvim_set_hl(0, "StatusLine", { bg = 15000780, fg = 3818040 })
vim.api.nvim_set_hl(0, "StatusLineNC", { bg = 15395536, fg = 10594208 })
vim.api.nvim_set_hl(0, "StorageClass", { cterm = { italic = true }, fg = 10976000, italic = true })
vim.api.nvim_set_hl(0, "String", { fg = 2589963 })
vim.api.nvim_set_hl(0, "Substitute", { bg = 2589963, fg = 16448224 })
vim.api.nvim_set_hl(0, "TabLine", { bg = 15395536, fg = 3818040 })
vim.api.nvim_set_hl(0, "TabLineFill", { bg = 15395536, fg = 10594208 })
vim.api.nvim_set_hl(0, "TabLineSel", { bg = 3818040, fg = 16448224 })
vim.api.nvim_set_hl(0, "Tag", { fg = 1525205 })
vim.api.nvim_set_hl(0, "Title", { bold = true, cterm = { bold = true }, fg = 1608350 })
vim.api.nvim_set_hl(0, "Todo", { bg = 9063135, bold = true, cterm = { bold = true }, fg = 16775408 })
vim.api.nvim_set_hl(0, "Type", { fg = 10976000 })
vim.api.nvim_set_hl(0, "Visual", { bg = 14342850 })
vim.api.nvim_set_hl(0, "VisualNOS", { bg = 15000780, cterm = { underline = true }, underline = true })
vim.api.nvim_set_hl(0, "WarningMsg", { bold = true, cterm = { bold = true }, fg = 10976000 })
vim.api.nvim_set_hl(0, "WildMenu", { bg = 1525205, fg = 16448224 })
vim.api.nvim_set_hl(0, "WinBar", { fg = 8619905 })
vim.api.nvim_set_hl(0, "WinBarNC", { link = "WinBar" })
vim.api.nvim_set_hl(0, "WinSeparator", { fg = 14342850 })
vim.api.nvim_set_hl(0, "diffChanged", { link = "PreProc" })
vim.api.nvim_set_hl(0, "diffNewFile", { link = "DiffFile" })
vim.api.nvim_set_hl(0, "diffOldFile", { link = "DiffFile" })
vim.api.nvim_set_hl(0, "htmlH1", { bold = true, cterm = { bold = true }, fg = 9773101 })
vim.api.nvim_set_hl(0, "htmlH2", { bold = true, cterm = { bold = true }, fg = 10961693 })
vim.api.nvim_set_hl(0, "htmlH3", { bold = true, cterm = { bold = true }, fg = 8215552 })
vim.api.nvim_set_hl(0, "htmlH4", { bold = true, cterm = { bold = true }, fg = 1926152 })
vim.api.nvim_set_hl(0, "htmlH5", { bold = true, cterm = { bold = true }, fg = 1206391 })
vim.api.nvim_set_hl(0, "htmlH6", { bold = true, cterm = { bold = true }, fg = 1127584 })
vim.api.nvim_set_hl(0, "lCursor", { link = "Cursor" })

364
nvim/colors/ex-bamboo.lua Normal file
View file

@ -0,0 +1,364 @@
-- This file is generated by ex-colors. The credit goes to the authors and contributors of the original colorscheme bamboo.
vim.api.nvim_set_var("colors_name", "ex-bamboo")
vim.api.nvim_set_var("terminal_color_0", "#111210")
vim.api.nvim_set_var("terminal_color_1", "#e75a7c")
vim.api.nvim_set_var("terminal_color_2", "#8fb573")
vim.api.nvim_set_var("terminal_color_3", "#dbb651")
vim.api.nvim_set_var("terminal_color_4", "#57a5e5")
vim.api.nvim_set_var("terminal_color_5", "#aaaaff")
vim.api.nvim_set_var("terminal_color_6", "#70c2be")
vim.api.nvim_set_var("terminal_color_7", "#f1e9d2")
vim.api.nvim_set_var("terminal_color_8", "#5b5e5a")
vim.api.nvim_set_var("terminal_color_9", "#e75a7c")
vim.api.nvim_set_var("terminal_color_10", "#8fb573")
vim.api.nvim_set_var("terminal_color_11", "#dbb651")
vim.api.nvim_set_var("terminal_color_12", "#57a5e5")
vim.api.nvim_set_var("terminal_color_13", "#aaaaff")
vim.api.nvim_set_var("terminal_color_14", "#70c2be")
vim.api.nvim_set_var("terminal_color_15", "#f1e9d2")
vim.api.nvim_set_option_value("background", "dark", {})
vim.api.nvim_set_hl(0, "@attribute", { fg = 7389886 })
vim.api.nvim_set_hl(0, "@character.special", { link = "Special" })
vim.api.nvim_set_hl(0, "@comment", { cterm = { italic = true }, fg = 14862226, italic = true })
vim.api.nvim_set_hl(0, "@comment.error", { bg = 15161980, bold = true, cterm = { bold = true }, fg = 1118736 })
vim.api.nvim_set_hl(0, "@comment.note", { bg = 5744101, bold = true, cterm = { bold = true }, fg = 1118736 })
vim.api.nvim_set_hl(0, "@comment.warning", { bg = 16750950, bold = true, cterm = { bold = true }, fg = 1118736 })
vim.api.nvim_set_hl(0, "@constant.builtin", { link = "Constant" })
vim.api.nvim_set_hl(0, "@constant.macro", { link = "Macro" })
vim.api.nvim_set_hl(0, "@constructor", { bold = true, cterm = { bold = true }, fg = 14399057 })
vim.api.nvim_set_hl(0, "@diff.delta", { link = "DiffChange" })
vim.api.nvim_set_hl(0, "@diff.minus", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "@diff.plus", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "@function.builtin", { bold = true, cterm = { bold = true }, fg = 16750950 })
vim.api.nvim_set_hl(0, "@function.call", { link = "Function" })
vim.api.nvim_set_hl(0, "@function.macro", { bold = true, cterm = { bold = true }, fg = 14644223 })
vim.api.nvim_set_hl(0, "@function.method", { link = "Function" })
vim.api.nvim_set_hl(0, "@function.method.call", { link = "Function" })
vim.api.nvim_set_hl(0, "@keyword.conditional", { link = "Conditional" })
vim.api.nvim_set_hl(0, "@keyword.conditional.ternary", { link = "Operator" })
vim.api.nvim_set_hl(0, "@keyword.coroutine", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@keyword.debug", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@keyword.directive", { link = "PreProc" })
vim.api.nvim_set_hl(0, "@keyword.directive.define", { bold = true, cterm = { bold = true }, fg = 11184895 })
vim.api.nvim_set_hl(0, "@keyword.exception", { link = "Exception" })
vim.api.nvim_set_hl(0, "@keyword.import", { link = "Include" })
vim.api.nvim_set_hl(0, "@keyword.modifier", { cterm = { italic = true }, fg = 11184895, italic = true })
vim.api.nvim_set_hl(0, "@keyword.operator", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@keyword.repeat", { link = "Repeat" })
vim.api.nvim_set_hl(0, "@keyword.return", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@keyword.type", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@lsp.mod.readonly", { link = "@constant" })
vim.api.nvim_set_hl(0, "@lsp.type.event", { link = "Label" })
vim.api.nvim_set_hl(0, "@lsp.type.macro", { link = "Macro" })
vim.api.nvim_set_hl(0, "@lsp.type.typeParameter", { link = "@type" })
vim.api.nvim_set_hl(0, "@markup.heading", { link = "htmlTitle" })
vim.api.nvim_set_hl(0, "@markup.heading.1", { link = "markdownH1" })
vim.api.nvim_set_hl(0, "@markup.heading.2", { link = "markdownH2" })
vim.api.nvim_set_hl(0, "@markup.heading.3", { link = "markdownH3" })
vim.api.nvim_set_hl(0, "@markup.heading.4", { link = "markdownH4" })
vim.api.nvim_set_hl(0, "@markup.heading.5", { link = "markdownH5" })
vim.api.nvim_set_hl(0, "@markup.heading.6", { link = "markdownH6" })
vim.api.nvim_set_hl(0, "@markup.italic", { link = "markdownItalic" })
vim.api.nvim_set_hl(0, "@markup.link", { link = "Tag" })
vim.api.nvim_set_hl(0, "@markup.link.label", { link = "markdownLinkText" })
vim.api.nvim_set_hl(0, "@markup.link.url", { link = "markdownUrl" })
vim.api.nvim_set_hl(0, "@markup.list", { link = "markdownListMarker" })
vim.api.nvim_set_hl(0, "@markup.list.checked", { bold = true, cterm = { bold = true }, fg = 14399057 })
vim.api.nvim_set_hl(0, "@markup.list.unchecked", { bold = true, cterm = { bold = true }, fg = 8619905 })
vim.api.nvim_set_hl(0, "@markup.math", { fg = 9881583 })
vim.api.nvim_set_hl(0, "@markup.quote", { fg = 8619905 })
vim.api.nvim_set_hl(0, "@markup.raw", { link = "markdownCode" })
vim.api.nvim_set_hl(0, "@markup.raw.block", { link = "markdownCodeBlock" })
vim.api.nvim_set_hl(0, "@markup.strikethrough", { link = "markdownStrike" })
vim.api.nvim_set_hl(0, "@markup.strong", { link = "markdownBold" })
vim.api.nvim_set_hl(0, "@markup.underline", { link = "htmlUnderline" })
vim.api.nvim_set_hl(0, "@module", { cterm = { italic = true }, fg = 9881583, italic = true })
vim.api.nvim_set_hl(0, "@module.builtin", { link = "@variable.builtin" })
vim.api.nvim_set_hl(0, "@property", { link = "@variable.member" })
vim.api.nvim_set_hl(0, "@punctuation.bracket", { link = "Delimiter" })
vim.api.nvim_set_hl(0, "@punctuation.delimiter", { link = "Delimiter" })
vim.api.nvim_set_hl(0, "@string.documentation", { fg = 11258006 })
vim.api.nvim_set_hl(0, "@string.escape", { fg = 15761536 })
vim.api.nvim_set_hl(0, "@string.regexp", { link = "Constant" })
vim.api.nvim_set_hl(0, "@string.special", { link = "Special" })
vim.api.nvim_set_hl(0, "@string.special.path", { cterm = { underline = true }, fg = 9881583, underline = true })
vim.api.nvim_set_hl(0, "@string.special.symbol", { link = "@variable.member" })
vim.api.nvim_set_hl(
0,
"@string.special.url",
{ cterm = { italic = true, underline = true }, fg = 7389886, italic = true, underline = true }
)
vim.api.nvim_set_hl(0, "@tag", { fg = 11184895 })
vim.api.nvim_set_hl(0, "@tag.attribute", { link = "@variable.member" })
vim.api.nvim_set_hl(0, "@tag.builtin", { link = "@tag" })
vim.api.nvim_set_hl(0, "@tag.delimiter", { link = "Delimiter" })
vim.api.nvim_set_hl(0, "@type.builtin", { link = "Type" })
vim.api.nvim_set_hl(0, "@type.definition", { link = "Type" })
vim.api.nvim_set_hl(0, "@variable", { fg = 15854034 })
vim.api.nvim_set_hl(0, "@variable.builtin", { fg = 15161980 })
vim.api.nvim_set_hl(0, "@variable.member", { fg = 7389886 })
vim.api.nvim_set_hl(0, "@variable.parameter", { cterm = { italic = true }, fg = 15761536, italic = true })
vim.api.nvim_set_hl(0, "@variable.parameter.builtin", { cterm = { italic = true }, fg = 15161980, italic = true })
vim.api.nvim_set_hl(0, "BlinkCmpCursorLineMenuHack", { bg = 3816759 })
vim.api.nvim_set_hl(0, "BlinkCmpDoc", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpDocBorder", { link = "FloatBorder" })
vim.api.nvim_set_hl(0, "BlinkCmpDocCursorLine", { link = "Visual" })
vim.api.nvim_set_hl(0, "BlinkCmpDocSeparator", { link = "NormalFloat" })
vim.api.nvim_set_hl(
0,
"BlinkCmpGhostText",
{ bg = 2434595, cterm = { italic = true, nocombine = true }, fg = 8619905, italic = true, nocombine = true }
)
vim.api.nvim_set_hl(0, "BlinkCmpKind", { fg = 11184895 })
vim.api.nvim_set_hl(0, "BlinkCmpKindArray", { fg = 14399057 })
vim.api.nvim_set_hl(0, "BlinkCmpKindBoolean", { fg = 16750950 })
vim.api.nvim_set_hl(0, "BlinkCmpKindClass", { fg = 14399057 })
vim.api.nvim_set_hl(0, "BlinkCmpKindCodeium", { fg = 15854034 })
vim.api.nvim_set_hl(0, "BlinkCmpKindColor", { fg = 9418099 })
vim.api.nvim_set_hl(0, "BlinkCmpKindConstant", { fg = 16750950 })
vim.api.nvim_set_hl(0, "BlinkCmpKindConstructor", { fg = 5744101 })
vim.api.nvim_set_hl(0, "BlinkCmpKindCopilot", { fg = 15854034 })
vim.api.nvim_set_hl(0, "BlinkCmpKindDefault", { fg = 11184895 })
vim.api.nvim_set_hl(0, "BlinkCmpKindEnum", { fg = 14399057 })
vim.api.nvim_set_hl(0, "BlinkCmpKindEnumMember", { fg = 16750950 })
vim.api.nvim_set_hl(0, "BlinkCmpKindEvent", { fg = 14399057 })
vim.api.nvim_set_hl(0, "BlinkCmpKindField", { fg = 7389886 })
vim.api.nvim_set_hl(0, "BlinkCmpKindFile", { fg = 9418099 })
vim.api.nvim_set_hl(0, "BlinkCmpKindFolder", { fg = 9881583 })
vim.api.nvim_set_hl(0, "BlinkCmpKindFunction", { fg = 5744101 })
vim.api.nvim_set_hl(0, "BlinkCmpKindInterface", { fg = 9418099 })
vim.api.nvim_set_hl(0, "BlinkCmpKindKey", { fg = 7389886 })
vim.api.nvim_set_hl(0, "BlinkCmpKindKeyword", { fg = 11184895 })
vim.api.nvim_set_hl(0, "BlinkCmpKindMethod", { fg = 5744101 })
vim.api.nvim_set_hl(0, "BlinkCmpKindModule", { fg = 9881583 })
vim.api.nvim_set_hl(0, "BlinkCmpKindNamespace", { fg = 9881583 })
vim.api.nvim_set_hl(0, "BlinkCmpKindNull", { fg = 5987930 })
vim.api.nvim_set_hl(0, "BlinkCmpKindNumber", { fg = 16750950 })
vim.api.nvim_set_hl(0, "BlinkCmpKindObject", { fg = 15161980 })
vim.api.nvim_set_hl(0, "BlinkCmpKindOperator", { fg = 12960494 })
vim.api.nvim_set_hl(0, "BlinkCmpKindPackage", { fg = 14399057 })
vim.api.nvim_set_hl(0, "BlinkCmpKindProperty", { fg = 7389886 })
vim.api.nvim_set_hl(0, "BlinkCmpKindReference", { fg = 16750950 })
vim.api.nvim_set_hl(0, "BlinkCmpKindSnippet", { cterm = { italic = true }, fg = 14644223, italic = true })
vim.api.nvim_set_hl(0, "BlinkCmpKindString", { fg = 9418099 })
vim.api.nvim_set_hl(0, "BlinkCmpKindStruct", { fg = 14399057 })
vim.api.nvim_set_hl(0, "BlinkCmpKindTabNine", { fg = 15854034 })
vim.api.nvim_set_hl(0, "BlinkCmpKindText", { fg = 8619905 })
vim.api.nvim_set_hl(0, "BlinkCmpKindTypeParameter", { fg = 15761536 })
vim.api.nvim_set_hl(0, "BlinkCmpKindUnit", { fg = 14399057 })
vim.api.nvim_set_hl(0, "BlinkCmpKindValue", { fg = 16750950 })
vim.api.nvim_set_hl(0, "BlinkCmpKindVariable", { fg = 15161980 })
vim.api.nvim_set_hl(0, "BlinkCmpLabel", { fg = 15854034 })
vim.api.nvim_set_hl(
0,
"BlinkCmpLabelDeprecated",
{ cterm = { strikethrough = true }, fg = 8619905, strikethrough = true }
)
vim.api.nvim_set_hl(0, "BlinkCmpLabelDescription", { fg = 8619905 })
vim.api.nvim_set_hl(0, "BlinkCmpLabelDetail", { link = "Comment" })
vim.api.nvim_set_hl(0, "BlinkCmpLabelMatch", { fg = 7389886 })
vim.api.nvim_set_hl(0, "BlinkCmpMenu", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpMenuBorder", { link = "FloatBorder" })
vim.api.nvim_set_hl(0, "BlinkCmpMenuSelection", { link = "PmenuSel" })
vim.api.nvim_set_hl(0, "BlinkCmpScrollBarGutter", { link = "PmenuSbar" })
vim.api.nvim_set_hl(0, "BlinkCmpScrollBarThumb", { link = "PmenuThumb" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelp", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelpActiveParameter", { link = "LspSignatureActiveParameter" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelpBorder", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpSource", { fg = 15854034 })
vim.api.nvim_set_hl(0, "ColorColumn", { bg = 3883573 })
vim.api.nvim_set_hl(0, "Comment", { cterm = { italic = true }, fg = 8619905, italic = true })
vim.api.nvim_set_hl(0, "Conceal", { fg = 8619905 })
vim.api.nvim_set_hl(0, "Conditional", { cterm = { italic = true }, fg = 11184895, italic = true })
vim.api.nvim_set_hl(0, "Constant", { fg = 16750950 })
vim.api.nvim_set_hl(0, "CurSearch", { bg = 16750950, fg = 2434595 })
vim.api.nvim_set_hl(0, "Cursor", { cterm = { reverse = true }, reverse = true })
vim.api.nvim_set_hl(0, "CursorColumn", { link = "CursorLine" })
vim.api.nvim_set_hl(0, "CursorLine", { bg = 3092780 })
vim.api.nvim_set_hl(0, "CursorLineNr", { fg = 15854034 })
vim.api.nvim_set_hl(0, "Debug", { fg = 16750950 })
vim.api.nvim_set_hl(0, "Delimiter", { fg = 8619905 })
vim.api.nvim_set_hl(0, "DiagnosticDeprecated", { link = "Strike" })
vim.api.nvim_set_hl(0, "DiagnosticError", { fg = 15161980 })
vim.api.nvim_set_hl(0, "DiagnosticHint", { fg = 11184895 })
vim.api.nvim_set_hl(0, "DiagnosticInfo", { fg = 7389886 })
vim.api.nvim_set_hl(0, "DiagnosticOk", { fg = 9418099 })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineError", { cterm = { undercurl = true }, sp = 15161980, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineHint", { cterm = { undercurl = true }, sp = 11184895, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineInfo", { cterm = { undercurl = true }, sp = 5744101, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineOk", { cterm = { undercurl = true }, sp = 9418099, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineWarn", { cterm = { undercurl = true }, sp = 14399057, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextError", { bg = 3418409, fg = 12142691 })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextHint", { bg = 3092532, fg = 8947916 })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextInfo", { bg = 2765359, fg = 5938072 })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextWarn", { bg = 3354918, fg = 11506241 })
vim.api.nvim_set_hl(0, "DiagnosticWarn", { fg = 14399057 })
vim.api.nvim_set_hl(0, "DiffAdd", { bg = 4215579 })
vim.api.nvim_set_hl(0, "DiffChange", { bg = 2767447 })
vim.api.nvim_set_hl(0, "DiffDelete", { bg = 8994629 })
vim.api.nvim_set_hl(0, "DiffText", { bg = 3820135 })
vim.api.nvim_set_hl(0, "Directory", { fg = 5744101 })
vim.api.nvim_set_hl(0, "EndOfBuffer", { fg = 2434595 })
vim.api.nvim_set_hl(0, "Error", { fg = 15161980 })
vim.api.nvim_set_hl(0, "ErrorMsg", { bold = true, cterm = { bold = true }, fg = 15161980 })
vim.api.nvim_set_hl(0, "Exception", { link = "Keyword" })
vim.api.nvim_set_hl(0, "Float", { link = "Constant" })
vim.api.nvim_set_hl(0, "FloatBorder", { bg = 2105631, fg = 11184895 })
vim.api.nvim_set_hl(0, "FloatFooter", { fg = 8619905 })
vim.api.nvim_set_hl(0, "FloatTitle", { fg = 15161980 })
vim.api.nvim_set_hl(0, "FoldColumn", { fg = 15854034 })
vim.api.nvim_set_hl(0, "Folded", { bg = 3092780, fg = 15854034 })
vim.api.nvim_set_hl(0, "Function", { bold = true, cterm = { bold = true }, fg = 5744101 })
vim.api.nvim_set_hl(0, "GitSignsAdd", { fg = 9418099 })
vim.api.nvim_set_hl(0, "GitSignsAddCul", { link = "GitSignsAdd" })
vim.api.nvim_set_hl(0, "GitSignsAddInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsAddLn", { fg = 9418099 })
vim.api.nvim_set_hl(0, "GitSignsAddLnInline", { link = "GitSignsAddInline" })
vim.api.nvim_set_hl(0, "GitSignsAddNr", { fg = 9418099 })
vim.api.nvim_set_hl(0, "GitSignsAddPreview", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "GitSignsChange", { fg = 5744101 })
vim.api.nvim_set_hl(0, "GitSignsChangeCul", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangeInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsChangeLn", { fg = 5744101 })
vim.api.nvim_set_hl(0, "GitSignsChangeLnInline", { link = "GitSignsChangeInline" })
vim.api.nvim_set_hl(0, "GitSignsChangeNr", { fg = 5744101 })
vim.api.nvim_set_hl(0, "GitSignsChangedelete", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteCul", { link = "GitSignsChangeCul" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteLn", { link = "GitSignsChangeLn" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteNr", { link = "GitSignsChangeNr" })
vim.api.nvim_set_hl(0, "GitSignsCurrentLineBlame", { link = "NonText" })
vim.api.nvim_set_hl(0, "GitSignsDelete", { fg = 15161980 })
vim.api.nvim_set_hl(0, "GitSignsDeleteCul", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsDeleteLn", { fg = 15161980 })
vim.api.nvim_set_hl(0, "GitSignsDeleteLnInline", { link = "GitSignsDeleteInline" })
vim.api.nvim_set_hl(0, "GitSignsDeleteNr", { fg = 15161980 })
vim.api.nvim_set_hl(0, "GitSignsDeletePreview", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteVirtLn", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteVirtLnInLine", { link = "GitSignsDeleteLnInline" })
vim.api.nvim_set_hl(0, "GitSignsStagedAdd", { fg = 4676153 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddCul", { fg = 4676153 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddLn", { fg = 4676153 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddNr", { fg = 4676153 })
vim.api.nvim_set_hl(0, "GitSignsStagedChange", { fg = 2839154 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeCul", { fg = 2839154 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeLn", { fg = 2839154 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeNr", { fg = 2839154 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedelete", { fg = 2839154 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteCul", { fg = 2839154 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteLn", { fg = 2839154 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteNr", { fg = 2839154 })
vim.api.nvim_set_hl(0, "GitSignsStagedDelete", { fg = 7548222 })
vim.api.nvim_set_hl(0, "GitSignsStagedDeleteCul", { fg = 7548222 })
vim.api.nvim_set_hl(0, "GitSignsStagedDeleteNr", { fg = 7548222 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdelete", { fg = 7548222 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteCul", { fg = 7548222 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteLn", { fg = 7548222 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteNr", { fg = 7548222 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntracked", { fg = 7166760 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedCul", { fg = 4676153 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedLn", { fg = 7166760 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedNr", { fg = 7166760 })
vim.api.nvim_set_hl(0, "GitSignsTopdelete", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteCul", { link = "GitSignsDeleteCul" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteLn", { link = "GitSignsDeleteLn" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteNr", { link = "GitSignsDeleteNr" })
vim.api.nvim_set_hl(0, "GitSignsUntracked", { fg = 14399057 })
vim.api.nvim_set_hl(0, "GitSignsUntrackedCul", { link = "GitSignsAddCul" })
vim.api.nvim_set_hl(0, "GitSignsUntrackedLn", { fg = 14399057 })
vim.api.nvim_set_hl(0, "GitSignsUntrackedNr", { fg = 14399057 })
vim.api.nvim_set_hl(0, "GitSignsVirtLnum", { link = "GitSignsDeleteVirtLn" })
vim.api.nvim_set_hl(0, "Identifier", { fg = 15161980 })
vim.api.nvim_set_hl(0, "Keyword", { bold = true, cterm = { bold = true }, fg = 11184895 })
vim.api.nvim_set_hl(0, "Label", { bold = true, cterm = { bold = true }, fg = 15161980 })
vim.api.nvim_set_hl(0, "LineNr", { fg = 5987930 })
vim.api.nvim_set_hl(0, "LspCodeLens", { link = "Comment" })
vim.api.nvim_set_hl(0, "LspCodeLensSeparator", { fg = 5987930 })
vim.api.nvim_set_hl(0, "LspInlayHint", { fg = 5987930 })
vim.api.nvim_set_hl(0, "LspReferenceRead", { bg = 3685173 })
vim.api.nvim_set_hl(0, "LspReferenceText", { bg = 3685173 })
vim.api.nvim_set_hl(0, "LspReferenceWrite", { bg = 3685173 })
vim.api.nvim_set_hl(0, "Macro", { fg = 14644223 })
vim.api.nvim_set_hl(0, "MatchParen", { bg = 5987930, bold = true, cterm = { bold = true }, fg = 16750950 })
vim.api.nvim_set_hl(0, "MiniStatuslineDevinfo", { bg = 3685173, fg = 15854034 })
vim.api.nvim_set_hl(0, "MiniStatuslineFileinfo", { bg = 3685173, fg = 15854034 })
vim.api.nvim_set_hl(0, "MiniStatuslineFilename", { bg = 3092780, fg = 5987930 })
vim.api.nvim_set_hl(0, "MiniStatuslineInactive", { bg = 2434595, fg = 5987930 })
vim.api.nvim_set_hl(
0,
"MiniStatuslineModeCommand",
{ bg = 14399057, bold = true, cterm = { bold = true }, fg = 2434595 }
)
vim.api.nvim_set_hl(0, "MiniStatuslineModeInsert", { bg = 5744101, bold = true, cterm = { bold = true }, fg = 2434595 })
vim.api.nvim_set_hl(0, "MiniStatuslineModeNormal", { bg = 9418099, bold = true, cterm = { bold = true }, fg = 2434595 })
vim.api.nvim_set_hl(0, "MiniStatuslineModeOther", { bg = 7389886, bold = true, cterm = { bold = true }, fg = 2434595 })
vim.api.nvim_set_hl(
0,
"MiniStatuslineModeReplace",
{ bg = 15161980, bold = true, cterm = { bold = true }, fg = 2434595 }
)
vim.api.nvim_set_hl(
0,
"MiniStatuslineModeVisual",
{ bg = 11184895, bold = true, cterm = { bold = true }, fg = 2434595 }
)
vim.api.nvim_set_hl(0, "ModeMsg", { bold = true, cterm = { bold = true }, fg = 9753038 })
vim.api.nvim_set_hl(0, "MoreMsg", { bold = true, cterm = { bold = true }, fg = 5744101 })
vim.api.nvim_set_hl(0, "NonText", { fg = 5987930 })
vim.api.nvim_set_hl(0, "Normal", { bg = 2434595, fg = 15854034 })
vim.api.nvim_set_hl(0, "NormalFloat", { bg = 2105631, fg = 15854034 })
vim.api.nvim_set_hl(0, "NormalNC", { bg = 2105631, fg = 8619905 })
vim.api.nvim_set_hl(0, "Operator", { fg = 12960494 })
vim.api.nvim_set_hl(0, "Pmenu", { bg = 3092780, fg = 15854034 })
vim.api.nvim_set_hl(0, "PmenuSbar", { bg = 3092780 })
vim.api.nvim_set_hl(0, "PmenuSel", { bg = 3816759 })
vim.api.nvim_set_hl(0, "PmenuThumb", { bg = 5987930 })
vim.api.nvim_set_hl(0, "PreProc", { fg = 11184895 })
vim.api.nvim_set_hl(0, "Question", { fg = 14399057 })
vim.api.nvim_set_hl(0, "QuickFixLine", { cterm = { underline = true }, fg = 5744101, underline = true })
vim.api.nvim_set_hl(0, "RainbowDelimiterBlue", { fg = 8502508 })
vim.api.nvim_set_hl(0, "RainbowDelimiterCyan", { fg = 9753038 })
vim.api.nvim_set_hl(0, "RainbowDelimiterGreen", { fg = 11258006 })
vim.api.nvim_set_hl(0, "RainbowDelimiterOrange", { fg = 16757644 })
vim.api.nvim_set_hl(0, "RainbowDelimiterRed", { fg = 15565725 })
vim.api.nvim_set_hl(0, "RainbowDelimiterViolet", { fg = 12566527 })
vim.api.nvim_set_hl(0, "RainbowDelimiterYellow", { fg = 14993533 })
vim.api.nvim_set_hl(0, "Repeat", { link = "Keyword" })
vim.api.nvim_set_hl(0, "Search", { bg = 14862226, fg = 2434595 })
vim.api.nvim_set_hl(0, "SignColumn", { fg = 15854034 })
vim.api.nvim_set_hl(0, "Special", { fg = 15161980 })
vim.api.nvim_set_hl(0, "SpecialComment", { link = "Comment" })
vim.api.nvim_set_hl(0, "SpecialKey", { link = "NonText" })
vim.api.nvim_set_hl(0, "SpellBad", { cterm = { undercurl = true }, sp = 15161980, undercurl = true })
vim.api.nvim_set_hl(0, "SpellCap", { cterm = { undercurl = true }, sp = 14399057, undercurl = true })
vim.api.nvim_set_hl(0, "SpellLocal", { cterm = { undercurl = true }, sp = 5744101, undercurl = true })
vim.api.nvim_set_hl(0, "SpellRare", { cterm = { undercurl = true }, sp = 11184895, undercurl = true })
vim.api.nvim_set_hl(0, "Statement", { fg = 11184895 })
vim.api.nvim_set_hl(0, "StatusLine", { bg = 3685173, fg = 15854034 })
vim.api.nvim_set_hl(0, "StatusLineNC", { bg = 3092780, fg = 5987930 })
vim.api.nvim_set_hl(0, "StorageClass", { cterm = { italic = true }, fg = 14399057, italic = true })
vim.api.nvim_set_hl(0, "String", { fg = 9418099 })
vim.api.nvim_set_hl(0, "Substitute", { bg = 9418099, fg = 2434595 })
vim.api.nvim_set_hl(0, "TabLine", { bg = 3092780, fg = 15854034 })
vim.api.nvim_set_hl(0, "TabLineFill", { bg = 3092780, fg = 5987930 })
vim.api.nvim_set_hl(0, "TabLineSel", { bg = 15854034, fg = 2434595 })
vim.api.nvim_set_hl(0, "Tag", { fg = 5744101 })
vim.api.nvim_set_hl(0, "Title", { bold = true, cterm = { bold = true }, fg = 7389886 })
vim.api.nvim_set_hl(0, "Todo", { bg = 11184895, bold = true, cterm = { bold = true }, fg = 1118736 })
vim.api.nvim_set_hl(0, "Type", { fg = 14399057 })
vim.api.nvim_set_hl(0, "Visual", { bg = 3816759 })
vim.api.nvim_set_hl(0, "VisualNOS", { bg = 3685173, cterm = { underline = true }, underline = true })
vim.api.nvim_set_hl(0, "WarningMsg", { bold = true, cterm = { bold = true }, fg = 14399057 })
vim.api.nvim_set_hl(0, "WildMenu", { bg = 5744101, fg = 2434595 })
vim.api.nvim_set_hl(0, "WinBar", { fg = 8619905 })
vim.api.nvim_set_hl(0, "WinBarNC", { link = "WinBar" })
vim.api.nvim_set_hl(0, "WinSeparator", { fg = 3816759 })
vim.api.nvim_set_hl(0, "diffNewFile", { link = "DiffFile" })
vim.api.nvim_set_hl(0, "diffOldFile", { link = "DiffFile" })
vim.api.nvim_set_hl(0, "htmlH1", { bold = true, cterm = { bold = true }, fg = 15565725 })
vim.api.nvim_set_hl(0, "htmlH2", { bold = true, cterm = { bold = true }, fg = 16757644 })
vim.api.nvim_set_hl(0, "htmlH3", { bold = true, cterm = { bold = true }, fg = 14993533 })
vim.api.nvim_set_hl(0, "htmlH4", { bold = true, cterm = { bold = true }, fg = 11258006 })
vim.api.nvim_set_hl(0, "htmlH5", { bold = true, cterm = { bold = true }, fg = 9753038 })
vim.api.nvim_set_hl(0, "htmlH6", { bold = true, cterm = { bold = true }, fg = 8502508 })
vim.api.nvim_set_hl(0, "lCursor", { link = "Cursor" })

293
nvim/colors/ex-bluloco.lua Normal file
View file

@ -0,0 +1,293 @@
-- This file is generated by ex-colors. The credit goes to the authors and contributors of the original colorscheme bluloco.
vim.api.nvim_set_var("colors_name", "ex-bluloco")
vim.api.nvim_set_var("terminal_color_0", "#111210")
vim.api.nvim_set_var("terminal_color_1", "#e75a7c")
vim.api.nvim_set_var("terminal_color_2", "#8fb573")
vim.api.nvim_set_var("terminal_color_3", "#dbb651")
vim.api.nvim_set_var("terminal_color_4", "#57a5e5")
vim.api.nvim_set_var("terminal_color_5", "#aaaaff")
vim.api.nvim_set_var("terminal_color_6", "#70c2be")
vim.api.nvim_set_var("terminal_color_7", "#f1e9d2")
vim.api.nvim_set_var("terminal_color_8", "#5b5e5a")
vim.api.nvim_set_var("terminal_color_9", "#e75a7c")
vim.api.nvim_set_var("terminal_color_10", "#8fb573")
vim.api.nvim_set_var("terminal_color_11", "#dbb651")
vim.api.nvim_set_var("terminal_color_12", "#57a5e5")
vim.api.nvim_set_var("terminal_color_13", "#aaaaff")
vim.api.nvim_set_var("terminal_color_14", "#70c2be")
vim.api.nvim_set_var("terminal_color_15", "#f1e9d2")
vim.api.nvim_set_hl(0, "@attribute", { fg = 5287343 })
vim.api.nvim_set_hl(0, "@comment", { fg = 6516099 })
vim.api.nvim_set_hl(0, "@constant", { fg = 10519038 })
vim.api.nvim_set_hl(0, "@constant.builtin", { fg = 1094654 })
vim.api.nvim_set_hl(0, "@constructor", { fg = 16737922 })
vim.api.nvim_set_hl(0, "@function", { fg = 4179564 })
vim.api.nvim_set_hl(0, "@function.builtin", { fg = 4179564 })
vim.api.nvim_set_hl(0, "@function.call", { fg = 4179564 })
vim.api.nvim_set_hl(0, "@function.method", { fg = 4179564 })
vim.api.nvim_set_hl(0, "@keyword", { link = "Statement" })
vim.api.nvim_set_hl(0, "@keyword.modifier", { link = "Statement" })
vim.api.nvim_set_hl(0, "@label", { fg = 5287343 })
vim.api.nvim_set_hl(0, "@lsp.mod.readonly", { link = "@constant" })
vim.api.nvim_set_hl(0, "@lsp.type.decorator", { link = "@label" })
vim.api.nvim_set_hl(0, "@lsp.type.event", { link = "@variable.parameter" })
vim.api.nvim_set_hl(0, "@lsp.type.macro", { link = "@label" })
vim.api.nvim_set_hl(0, "@lsp.type.regexp", { link = "@string" })
vim.api.nvim_set_hl(0, "@lsp.type.typeParameter", { link = "@type" })
vim.api.nvim_set_hl(0, "@markup.heading", { fg = 1094654 })
vim.api.nvim_set_hl(0, "@markup.heading.1", { link = "RainbowRed" })
vim.api.nvim_set_hl(0, "@markup.heading.2", { link = "RainbowYellow" })
vim.api.nvim_set_hl(0, "@markup.heading.3", { link = "RainbowBlue" })
vim.api.nvim_set_hl(0, "@markup.heading.4", { link = "RainbowOrange" })
vim.api.nvim_set_hl(0, "@markup.heading.5", { link = "RainbowGreen" })
vim.api.nvim_set_hl(0, "@markup.heading.6", { link = "RainbowViolet" })
vim.api.nvim_set_hl(0, "@markup.link.url", { link = "@markup.url" })
vim.api.nvim_set_hl(0, "@markup.list", { link = "@punctuation.special" })
vim.api.nvim_set_hl(0, "@markup.raw", { link = "Property" })
vim.api.nvim_set_hl(0, "@markup.strong", { link = "Bold" })
vim.api.nvim_set_hl(0, "@markup.underline", { link = "Underlined" })
vim.api.nvim_set_hl(0, "@module", { fg = 16745885 })
vim.api.nvim_set_hl(0, "@number", { fg = 16743160 })
vim.api.nvim_set_hl(0, "@operator", { fg = 8160474 })
vim.api.nvim_set_hl(0, "@property", { link = "Property" })
vim.api.nvim_set_hl(0, "@punctuation.bracket", { fg = 8160474 })
vim.api.nvim_set_hl(0, "@punctuation.delimiter", { fg = 8160474 })
vim.api.nvim_set_hl(0, "@punctuation.special", { fg = 8160474 })
vim.api.nvim_set_hl(0, "@string.escape", { link = "Character" })
vim.api.nvim_set_hl(0, "@string.special.symbol", { fg = 10519038 })
vim.api.nvim_set_hl(0, "@string.special.url", { link = "@markup.url" })
vim.api.nvim_set_hl(0, "@tag.attribute", { cterm = { italic = true }, fg = 16749931, italic = true })
vim.api.nvim_set_hl(0, "@tag.builtin", { link = "Tag" })
vim.api.nvim_set_hl(0, "@type.builtin", { fg = 1094654 })
vim.api.nvim_set_hl(0, "@variable", { link = "Identifier" })
vim.api.nvim_set_hl(0, "@variable.builtin", { link = "Statement" })
vim.api.nvim_set_hl(0, "@variable.member", { link = "Property" })
vim.api.nvim_set_hl(0, "@variable.parameter", { fg = 9096687 })
vim.api.nvim_set_hl(0, "Added", { fg = 4179564 })
vim.api.nvim_set_hl(0, "BlinkCmpCursorLineMenuHack", { bg = 2639473 })
vim.api.nvim_set_hl(0, "BlinkCmpDoc", { bg = 2171692, fg = 11252415 })
vim.api.nvim_set_hl(0, "BlinkCmpDocBorder", { bg = 2171692, fg = 8160474 })
vim.api.nvim_set_hl(0, "BlinkCmpDocCursorLine", { link = "Visual" })
vim.api.nvim_set_hl(0, "BlinkCmpDocSeparator", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpGhostText", { link = "NonText" })
vim.api.nvim_set_hl(0, "BlinkCmpKind", { link = "Special" })
vim.api.nvim_set_hl(0, "BlinkCmpKindClass", { fg = 16737922 })
vim.api.nvim_set_hl(0, "BlinkCmpKindCodeium", { fg = 9873954 })
vim.api.nvim_set_hl(0, "BlinkCmpKindColor", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindConstant", { fg = 10519038 })
vim.api.nvim_set_hl(0, "BlinkCmpKindConstructor", { fg = 16737922 })
vim.api.nvim_set_hl(0, "BlinkCmpKindCopilot", { fg = 9873954 })
vim.api.nvim_set_hl(0, "BlinkCmpKindEnum", { fg = 16737922 })
vim.api.nvim_set_hl(0, "BlinkCmpKindEnumMember", { fg = 16737922 })
vim.api.nvim_set_hl(0, "BlinkCmpKindEvent", { fg = 5287343 })
vim.api.nvim_set_hl(0, "BlinkCmpKindField", { fg = 13539464 })
vim.api.nvim_set_hl(0, "BlinkCmpKindFile", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindFolder", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindFunction", { fg = 4179564 })
vim.api.nvim_set_hl(0, "BlinkCmpKindInterface", { fg = 16737922 })
vim.api.nvim_set_hl(0, "BlinkCmpKindKeyword", { fg = 1094654 })
vim.api.nvim_set_hl(0, "BlinkCmpKindMethod", { fg = 4179564 })
vim.api.nvim_set_hl(0, "BlinkCmpKindModule", { fg = 1094654 })
vim.api.nvim_set_hl(0, "BlinkCmpKindOperator", { fg = 8160474 })
vim.api.nvim_set_hl(0, "BlinkCmpKindProperty", { fg = 13539464 })
vim.api.nvim_set_hl(0, "BlinkCmpKindReference", { fg = 11252415 })
vim.api.nvim_set_hl(0, "BlinkCmpKindSnippet", { fg = 5287343 })
vim.api.nvim_set_hl(0, "BlinkCmpKindStruct", { fg = 16737922 })
vim.api.nvim_set_hl(0, "BlinkCmpKindSupermaven", { fg = 9873954 })
vim.api.nvim_set_hl(0, "BlinkCmpKindTabNine", { fg = 9873954 })
vim.api.nvim_set_hl(0, "BlinkCmpKindText", { fg = 6516099 })
vim.api.nvim_set_hl(0, "BlinkCmpKindTypeParameter", { fg = 16737922 })
vim.api.nvim_set_hl(0, "BlinkCmpKindUnit", { fg = 16743160 })
vim.api.nvim_set_hl(0, "BlinkCmpKindValue", { fg = 11252415 })
vim.api.nvim_set_hl(0, "BlinkCmpKindVariable", { fg = 11252415 })
vim.api.nvim_set_hl(0, "BlinkCmpLabel", { fg = 11252415 })
vim.api.nvim_set_hl(
0,
"BlinkCmpLabelDeprecated",
{ cterm = { strikethrough = true }, fg = 11252415, strikethrough = true }
)
vim.api.nvim_set_hl(0, "BlinkCmpLabelDescription", { fg = 16749931 })
vim.api.nvim_set_hl(0, "BlinkCmpLabelDetail", { fg = 16749931 })
vim.api.nvim_set_hl(0, "BlinkCmpLabelMatch", { fg = 3707647 })
vim.api.nvim_set_hl(0, "BlinkCmpMenu", { link = "Pmenu" })
vim.api.nvim_set_hl(0, "BlinkCmpMenuBorder", { link = "Pmenu" })
vim.api.nvim_set_hl(0, "BlinkCmpMenuSelection", { link = "PmenuSel" })
vim.api.nvim_set_hl(0, "BlinkCmpScrollBarGutter", { link = "PmenuSbar" })
vim.api.nvim_set_hl(0, "BlinkCmpScrollBarThumb", { link = "PmenuThumb" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelp", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelpActiveParameter", { link = "LspSignatureActiveParameter" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelpBorder", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpSource", { fg = 16749931 })
vim.api.nvim_set_hl(0, "Boolean", { cterm = { italic = true }, fg = 1094654, italic = true })
vim.api.nvim_set_hl(0, "Changed", { fg = 3707647 })
vim.api.nvim_set_hl(0, "Character", { fg = 16749931 })
vim.api.nvim_set_hl(0, "ColorColumn", { bg = 3357256 })
vim.api.nvim_set_hl(0, "Comment", { cterm = { italic = true }, fg = 6516099, italic = true })
vim.api.nvim_set_hl(0, "Constant", { fg = 10519038 })
vim.api.nvim_set_hl(0, "CurSearch", { link = "Search" })
vim.api.nvim_set_hl(0, "Cursor", { bg = 16763904, fg = 2632756 })
vim.api.nvim_set_hl(0, "CursorColumn", { link = "CursorLine" })
vim.api.nvim_set_hl(0, "CursorLine", { bg = 3686994 })
vim.api.nvim_set_hl(0, "CursorLineNr", { fg = 6516099 })
vim.api.nvim_set_hl(0, "DiagnosticError", { link = "Error" })
vim.api.nvim_set_hl(0, "DiagnosticHint", { fg = 7832026 })
vim.api.nvim_set_hl(0, "DiagnosticInfo", { fg = 3707647 })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineError", { cterm = { undercurl = true }, sp = 16723519, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineHint", { cterm = { undercurl = true }, sp = 7832026, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineInfo", { cterm = { undercurl = true }, sp = 3707647, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticUnderlineWarn", { cterm = { undercurl = true }, sp = 14318404, undercurl = true })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextError", { bg = 4995140, fg = 16723519 })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextHint", { bg = 3685975, fg = 7832026 })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextInfo", { bg = 3162458, fg = 3707647 })
vim.api.nvim_set_hl(0, "DiagnosticVirtualTextWarn", { bg = 4603713, fg = 14318404 })
vim.api.nvim_set_hl(0, "DiagnosticWarn", { link = "WarningMsg" })
vim.api.nvim_set_hl(0, "DiffAdd", { bg = 1071933 })
vim.api.nvim_set_hl(0, "DiffChange", { bg = 1065307 })
vim.api.nvim_set_hl(0, "DiffDelete", { bg = 5385780 })
vim.api.nvim_set_hl(0, "DiffText", { bg = 1531266 })
vim.api.nvim_set_hl(0, "Directory", { fg = 1094654 })
vim.api.nvim_set_hl(0, "EndOfBuffer", { fg = 8160474 })
vim.api.nvim_set_hl(0, "Error", { link = "ErrorMsg" })
vim.api.nvim_set_hl(0, "ErrorMsg", { fg = 16723519 })
vim.api.nvim_set_hl(0, "FloatBorder", { fg = 8160474 })
vim.api.nvim_set_hl(0, "Folded", { bg = 3488581, fg = 3707647 })
vim.api.nvim_set_hl(0, "Function", { fg = 4179564 })
vim.api.nvim_set_hl(0, "GitSignsAdd", { fg = 1539412 })
vim.api.nvim_set_hl(0, "GitSignsAddCul", { link = "GitSignsAdd" })
vim.api.nvim_set_hl(0, "GitSignsAddInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsAddLn", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "GitSignsAddLnInline", { link = "GitSignsAddInline" })
vim.api.nvim_set_hl(0, "GitSignsAddNr", { link = "GitSignsAdd" })
vim.api.nvim_set_hl(0, "GitSignsAddPreview", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "GitSignsChange", { fg = 1863580 })
vim.api.nvim_set_hl(0, "GitSignsChangeCul", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangeInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsChangeLn", { link = "DiffChange" })
vim.api.nvim_set_hl(0, "GitSignsChangeLnInline", { link = "GitSignsChangeInline" })
vim.api.nvim_set_hl(0, "GitSignsChangeNr", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangedelete", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteCul", { link = "GitSignsChangeCul" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteLn", { link = "GitSignsChangeLn" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteNr", { link = "GitSignsChangeNr" })
vim.api.nvim_set_hl(0, "GitSignsCurrentLineBlame", { link = "NonText" })
vim.api.nvim_set_hl(0, "GitSignsDelete", { fg = 10636892 })
vim.api.nvim_set_hl(0, "GitSignsDeleteCul", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsDeleteLnInline", { link = "GitSignsDeleteInline" })
vim.api.nvim_set_hl(0, "GitSignsDeleteNr", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeletePreview", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteVirtLn", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteVirtLnInLine", { link = "GitSignsDeleteLnInline" })
vim.api.nvim_set_hl(0, "GitSignsStagedAdd", { bg = 1539412, fg = 2632756 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddCul", { link = "GitSignsStagedAdd" })
vim.api.nvim_set_hl(0, "GitSignsStagedAddLn", { bg = 1071933 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddNr", { link = "GitSignsStagedAdd" })
vim.api.nvim_set_hl(0, "GitSignsStagedChange", { bg = 1863580, fg = 2632756 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeCul", { link = "GitSignsStagedChange" })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeLn", { bg = 1065307 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeNr", { link = "GitSignsStagedChange" })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedelete", { link = "GitSignsStagedDelete" })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteCul", { link = "GitSignsStagedChangedelete" })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteLn", { bg = 1065307 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteNr", { link = "GitSignsStagedChangedelete" })
vim.api.nvim_set_hl(0, "GitSignsStagedDelete", { bg = 10636892, fg = 2632756 })
vim.api.nvim_set_hl(0, "GitSignsStagedDeleteCul", { link = "GitSignsStagedDelete" })
vim.api.nvim_set_hl(0, "GitSignsStagedDeleteNr", { link = "GitSignsStagedDelete" })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdelete", { link = "GitSignsStagedDelete" })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteCul", { link = "GitSignsStagedTopdelete" })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteNr", { link = "GitSignsStagedTopdelete" })
vim.api.nvim_set_hl(0, "GitSignsStagedUntracked", { link = "GitSignsStagedAdd" })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedCul", { link = "GitSignsStagedUntracked" })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedLn", { bg = 1071933 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedNr", { link = "GitSignsStagedUntracked" })
vim.api.nvim_set_hl(0, "GitSignsTopdelete", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteCul", { link = "GitSignsDeleteCul" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteLn", { link = "GitSignsDeleteLn" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteNr", { link = "GitSignsDeleteNr" })
vim.api.nvim_set_hl(0, "GitSignsUntracked", { link = "GitSignsAdd" })
vim.api.nvim_set_hl(0, "GitSignsUntrackedCul", { link = "GitSignsUntracked" })
vim.api.nvim_set_hl(0, "GitSignsUntrackedLn", { link = "GitSignsAddLn" })
vim.api.nvim_set_hl(0, "GitSignsUntrackedNr", { link = "GitSignsUntracked" })
vim.api.nvim_set_hl(0, "GitSignsVirtLnum", { link = "GitSignsDeleteVirtLn" })
vim.api.nvim_set_hl(0, "Identifier", { fg = 11252415 })
vim.api.nvim_set_hl(0, "Ignore", { fg = 2632756 })
vim.api.nvim_set_hl(0, "IncSearch", { bg = 14923789, fg = 2632756 })
vim.api.nvim_set_hl(0, "LineNr", { fg = 6516099 })
vim.api.nvim_set_hl(0, "LspCodeLens", { link = "WarningMsg" })
vim.api.nvim_set_hl(0, "LspCodeLensSeparator", { link = "Boolean" })
vim.api.nvim_set_hl(0, "LspInlayHint", { bg = 2896186, fg = 5726064 })
vim.api.nvim_set_hl(0, "MatchParen", { bg = 8160474, fg = 2632756 })
vim.api.nvim_set_hl(0, "MiniStatuslineDevinfo", { link = "StatusLine" })
vim.api.nvim_set_hl(0, "MiniStatuslineFileinfo", { link = "StatusLine" })
vim.api.nvim_set_hl(0, "MiniStatuslineFilename", { link = "StatusLineNC" })
vim.api.nvim_set_hl(0, "MiniStatuslineInactive", { link = "StatusLineNC" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeCommand", { link = "DiffText" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeInsert", { link = "DiffChange" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeNormal", { link = "Cursor" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeOther", { link = "IncSearch" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeReplace", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeVisual", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "ModeMsg", { link = "Normal" })
vim.api.nvim_set_hl(0, "MoreMsg", { fg = 3707647 })
vim.api.nvim_set_hl(0, "MsgArea", { link = "Normal" })
vim.api.nvim_set_hl(0, "NonText", { fg = 6252924 })
vim.api.nvim_set_hl(0, "Normal", { bg = 2632756, fg = 11252415 })
vim.api.nvim_set_hl(0, "NormalFloat", { bg = 2171692, blend = 5 })
vim.api.nvim_set_hl(0, "NormalNC", { link = "Normal" })
vim.api.nvim_set_hl(0, "Number", { fg = 16743160 })
vim.api.nvim_set_hl(0, "Operator", { fg = 8160474 })
vim.api.nvim_set_hl(0, "Pmenu", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "PmenuSbar", { bg = 3357256 })
vim.api.nvim_set_hl(0, "PmenuSel", { bg = 2639473 })
vim.api.nvim_set_hl(0, "PmenuThumb", { bg = 8160474 })
vim.api.nvim_set_hl(0, "PreProc", { fg = 1094654 })
vim.api.nvim_set_hl(0, "Question", { fg = 3707647 })
vim.api.nvim_set_hl(0, "QuickFixLine", { bg = 3707647, fg = 16777215 })
vim.api.nvim_set_hl(0, "RainbowDelimiterBlue", { fg = 4367615 })
vim.api.nvim_set_hl(0, "RainbowDelimiterCyan", { fg = 2680299 })
vim.api.nvim_set_hl(0, "RainbowDelimiterGreen", { fg = 9565490 })
vim.api.nvim_set_hl(0, "RainbowDelimiterOrange", { fg = 16752676 })
vim.api.nvim_set_hl(0, "RainbowDelimiterRed", { fg = 16737894 })
vim.api.nvim_set_hl(0, "RainbowDelimiterViolet", { fg = 16743167 })
vim.api.nvim_set_hl(0, "RainbowDelimiterYellow", { fg = 16056186 })
vim.api.nvim_set_hl(0, "Removed", { fg = 16737922 })
vim.api.nvim_set_hl(0, "Search", { bg = 1667142 })
vim.api.nvim_set_hl(0, "SignColumn", { link = "Normal" })
vim.api.nvim_set_hl(0, "Special", { link = "Character" })
vim.api.nvim_set_hl(0, "SpecialKey", { fg = 16749931 })
vim.api.nvim_set_hl(0, "Statement", { cterm = { italic = true }, fg = 1094654, italic = true })
vim.api.nvim_set_hl(0, "StatusLine", { bg = 3950941 })
vim.api.nvim_set_hl(0, "StatusLineNC", { bg = 3225151 })
vim.api.nvim_set_hl(0, "String", { fg = 16370008 })
vim.api.nvim_set_hl(0, "Substitute", { link = "IncSearch" })
vim.api.nvim_set_hl(0, "TabLine", { bg = 2896186, fg = 6252924 })
vim.api.nvim_set_hl(0, "TabLineFill", { bg = 2632756 })
vim.api.nvim_set_hl(0, "TabLineSel", { bg = 3817291, cterm = { underline = true }, sp = 3707647, underline = true })
vim.api.nvim_set_hl(0, "Tag", { fg = 3707647 })
vim.api.nvim_set_hl(0, "TermCursor", { link = "Cursor" })
vim.api.nvim_set_hl(0, "Title", { fg = 3707647 })
vim.api.nvim_set_hl(0, "Todo", { bg = 3707647, fg = 16777215 })
vim.api.nvim_set_hl(0, "Type", { fg = 16737922 })
vim.api.nvim_set_hl(0, "Visual", { bg = 2639473 })
vim.api.nvim_set_hl(0, "VisualNOS", { bg = 2639473 })
vim.api.nvim_set_hl(0, "WarningMsg", { fg = 14318404 })
vim.api.nvim_set_hl(0, "Whitespace", { fg = 3950941 })
vim.api.nvim_set_hl(0, "WildMenu", { bg = 2639473 })
vim.api.nvim_set_hl(0, "WinBar", { bold = true, cterm = { bold = true }, fg = 3707647 })
vim.api.nvim_set_hl(0, "WinBarNC", { fg = 11252415 })
vim.api.nvim_set_hl(0, "WinSeparator", { fg = 5926284 })
vim.api.nvim_set_hl(0, "diffAdded", { fg = 4179564 })
vim.api.nvim_set_hl(0, "diffChanged", { link = "PreProc" })
vim.api.nvim_set_hl(0, "diffIndexLine", { fg = 9096687 })
vim.api.nvim_set_hl(0, "diffLine", { fg = 16743160 })
vim.api.nvim_set_hl(0, "diffNewFile", { fg = 10519038 })
vim.api.nvim_set_hl(0, "diffOldFile", { fg = 13539464 })
vim.api.nvim_set_hl(0, "diffRemoved", { fg = 16737922 })
vim.api.nvim_set_hl(0, "diffSubname", { fg = 16370008 })
vim.api.nvim_set_hl(0, "lCursor", { link = "Cursor" })
vim.api.nvim_set_hl(0, "markdownH1", { link = "RainbowRed" })
vim.api.nvim_set_hl(0, "markdownH2", { link = "RainbowYellow" })
vim.api.nvim_set_hl(0, "markdownH3", { link = "RainbowBlue" })
vim.api.nvim_set_hl(0, "markdownH4", { link = "RainbowOrange" })
vim.api.nvim_set_hl(0, "markdownH5", { link = "RainbowGreen" })
vim.api.nvim_set_hl(0, "markdownH6", { link = "RainbowViolet" })

155
nvim/colors/ex-pustota.lua Normal file
View file

@ -0,0 +1,155 @@
-- This file is generated by ex-colors. The credit goes to the authors and contributors of the original colorscheme pustota.
vim.api.nvim_set_var("colors_name", "ex-pustota")
vim.api.nvim_set_hl(0, "@constant", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@constant.builtin", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@function.call", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@function.macro", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@function.method.call", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@keyword.directive", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@module", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@module.builtin", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@punctuation.bracket", { link = "Bracket" })
vim.api.nvim_set_hl(0, "@punctuation.delimiter", { link = "Bracket" })
vim.api.nvim_set_hl(0, "@punctuation.special", { link = "Bracket" })
vim.api.nvim_set_hl(0, "@string.escape", { link = "String" })
vim.api.nvim_set_hl(0, "@type", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@type.definition", { link = "Type" })
vim.api.nvim_set_hl(0, "@variable", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@variable.builtin", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@variable.member", { fg = 11776429 })
vim.api.nvim_set_hl(0, "@variable.parameter", { fg = 11776429 })
vim.api.nvim_set_hl(0, "BlinkCmpDoc", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpDocBorder", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpDocCursorLine", { link = "Visual" })
vim.api.nvim_set_hl(0, "BlinkCmpDocSeparator", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpGhostText", { link = "NonText" })
vim.api.nvim_set_hl(0, "BlinkCmpKind", { link = "PmenuKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindClass", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindColor", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindConstant", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindConstructor", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindEnum", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindEnumMember", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindEvent", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindField", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindFile", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindFolder", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindFunction", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindInterface", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindKeyword", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindMethod", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindModule", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindOperator", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindProperty", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindReference", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindSnippet", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindStruct", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindText", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindTypeParameter", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindUnit", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindValue", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpKindVariable", { link = "BlinkCmpKind" })
vim.api.nvim_set_hl(0, "BlinkCmpLabelDeprecated", { link = "PmenuExtra" })
vim.api.nvim_set_hl(0, "BlinkCmpLabelDescription", { link = "PmenuExtra" })
vim.api.nvim_set_hl(0, "BlinkCmpLabelDetail", { link = "PmenuExtra" })
vim.api.nvim_set_hl(0, "BlinkCmpMenu", { link = "Pmenu" })
vim.api.nvim_set_hl(0, "BlinkCmpMenuBorder", { link = "Pmenu" })
vim.api.nvim_set_hl(0, "BlinkCmpMenuSelection", { link = "PmenuSel" })
vim.api.nvim_set_hl(0, "BlinkCmpScrollBarGutter", { link = "PmenuSbar" })
vim.api.nvim_set_hl(0, "BlinkCmpScrollBarThumb", { link = "PmenuThumb" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelp", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelpActiveParameter", { link = "LspSignatureActiveParameter" })
vim.api.nvim_set_hl(0, "BlinkCmpSignatureHelpBorder", { link = "NormalFloat" })
vim.api.nvim_set_hl(0, "BlinkCmpSource", { link = "PmenuExtra" })
vim.api.nvim_set_hl(0, "Character", { fg = 12769612 })
vim.api.nvim_set_hl(0, "Comment", { cterm = { italic = true }, fg = 6449779, italic = true })
vim.api.nvim_set_hl(0, "Conceal", { fg = 5198424 })
vim.api.nvim_set_hl(0, "Conditional", { fg = 16748352 })
vim.api.nvim_set_hl(0, "Constant", { fg = 15119440 })
vim.api.nvim_set_hl(0, "Cursor", { bg = 11776429, fg = 658964 })
vim.api.nvim_set_hl(0, "Exception", { fg = 16748352 })
vim.api.nvim_set_hl(0, "Function", { fg = 16757844 })
vim.api.nvim_set_hl(0, "GitSignsAdd", { link = "Added" })
vim.api.nvim_set_hl(0, "GitSignsAddCul", { link = "GitSignsAdd" })
vim.api.nvim_set_hl(0, "GitSignsAddInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsAddLn", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "GitSignsAddLnInline", { link = "GitSignsAddInline" })
vim.api.nvim_set_hl(0, "GitSignsAddNr", { link = "GitSignsAdd" })
vim.api.nvim_set_hl(0, "GitSignsAddPreview", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "GitSignsChange", { link = "Changed" })
vim.api.nvim_set_hl(0, "GitSignsChangeCul", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangeInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsChangeLn", { link = "DiffChange" })
vim.api.nvim_set_hl(0, "GitSignsChangeLnInline", { link = "GitSignsChangeInline" })
vim.api.nvim_set_hl(0, "GitSignsChangeNr", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangedelete", { link = "GitSignsChange" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteCul", { link = "GitSignsChangeCul" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteLn", { link = "GitSignsChangeLn" })
vim.api.nvim_set_hl(0, "GitSignsChangedeleteNr", { link = "GitSignsChangeNr" })
vim.api.nvim_set_hl(0, "GitSignsCurrentLineBlame", { link = "NonText" })
vim.api.nvim_set_hl(0, "GitSignsDelete", { link = "Removed" })
vim.api.nvim_set_hl(0, "GitSignsDeleteCul", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteInline", { link = "TermCursor" })
vim.api.nvim_set_hl(0, "GitSignsDeleteLnInline", { link = "GitSignsDeleteInline" })
vim.api.nvim_set_hl(0, "GitSignsDeleteNr", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeletePreview", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteVirtLn", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "GitSignsDeleteVirtLnInLine", { link = "GitSignsDeleteLnInline" })
vim.api.nvim_set_hl(0, "GitSignsStagedAdd", { fg = 5864288 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddCul", { fg = 5864288 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddLn", { bg = 21795, fg = 7829628 })
vim.api.nvim_set_hl(0, "GitSignsStagedAddNr", { fg = 5864288 })
vim.api.nvim_set_hl(0, "GitSignsStagedChange", { fg = 4619387 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeCul", { fg = 4619387 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeLn", { bg = 5198424, fg = 7829628 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangeNr", { fg = 4619387 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedelete", { fg = 4619387 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteCul", { fg = 4619387 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteLn", { bg = 5198424, fg = 7829628 })
vim.api.nvim_set_hl(0, "GitSignsStagedChangedeleteNr", { fg = 4619387 })
vim.api.nvim_set_hl(0, "GitSignsStagedDelete", { fg = 8347740 })
vim.api.nvim_set_hl(0, "GitSignsStagedDeleteCul", { fg = 8347740 })
vim.api.nvim_set_hl(0, "GitSignsStagedDeleteNr", { fg = 8347740 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdelete", { fg = 8347740 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteCul", { fg = 8347740 })
vim.api.nvim_set_hl(0, "GitSignsStagedTopdeleteNr", { fg = 8347740 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntracked", { fg = 5864288 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedCul", { fg = 5864288 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedLn", { bg = 21795, fg = 7829628 })
vim.api.nvim_set_hl(0, "GitSignsStagedUntrackedNr", { fg = 5864288 })
vim.api.nvim_set_hl(0, "GitSignsTopdelete", { link = "GitSignsDelete" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteCul", { link = "GitSignsDeleteCul" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteLn", { link = "GitSignsDeleteLn" })
vim.api.nvim_set_hl(0, "GitSignsTopdeleteNr", { link = "GitSignsDeleteNr" })
vim.api.nvim_set_hl(0, "GitSignsUntracked", { link = "GitSignsAdd" })
vim.api.nvim_set_hl(0, "GitSignsUntrackedCul", { link = "GitSignsAddCul" })
vim.api.nvim_set_hl(0, "GitSignsUntrackedLn", { link = "GitSignsAddLn" })
vim.api.nvim_set_hl(0, "GitSignsUntrackedNr", { link = "GitSignsAddNr" })
vim.api.nvim_set_hl(0, "GitSignsVirtLnum", { link = "GitSignsDeleteVirtLn" })
vim.api.nvim_set_hl(0, "Keyword", { fg = 16748352 })
vim.api.nvim_set_hl(0, "Label", { fg = 16748352 })
vim.api.nvim_set_hl(0, "MiniStatuslineDevinfo", { link = "StatusLine" })
vim.api.nvim_set_hl(0, "MiniStatuslineFileinfo", { link = "StatusLine" })
vim.api.nvim_set_hl(0, "MiniStatuslineFilename", { link = "StatusLineNC" })
vim.api.nvim_set_hl(0, "MiniStatuslineInactive", { link = "StatusLineNC" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeCommand", { link = "DiffText" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeInsert", { link = "DiffChange" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeNormal", { link = "Cursor" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeOther", { link = "IncSearch" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeReplace", { link = "DiffDelete" })
vim.api.nvim_set_hl(0, "MiniStatuslineModeVisual", { link = "DiffAdd" })
vim.api.nvim_set_hl(0, "Normal", { bg = 658964, fg = 11776429 })
vim.api.nvim_set_hl(0, "Operator", { fg = 16748352 })
vim.api.nvim_set_hl(0, "PreProc", { fg = 11776429 })
vim.api.nvim_set_hl(0, "Repeat", { fg = 16748352 })
vim.api.nvim_set_hl(0, "Special", { fg = 11776429 })
vim.api.nvim_set_hl(0, "Statement", { fg = 16748352 })
vim.api.nvim_set_hl(0, "String", { fg = 12769612 })
vim.api.nvim_set_hl(0, "Type", { fg = 5882623 })
vim.api.nvim_set_hl(0, "Visual", { bg = 1844785 })
vim.api.nvim_set_hl(0, "diffAdded", { link = "Identifier" })
vim.api.nvim_set_hl(0, "diffChanged", { link = "PreProc" })
vim.api.nvim_set_hl(0, "diffNewFile", { link = "DiffFile" })
vim.api.nvim_set_hl(0, "diffOldFile", { link = "DiffFile" })
vim.api.nvim_set_hl(0, "diffRemoved", { link = "Special" })
vim.api.nvim_set_hl(0, "lCursor", { bg = 11776429, fg = 658964 })

79
nvim/filetype.lua Normal file
View file

@ -0,0 +1,79 @@
local function vim2ext(t, s, ft)
for k in string.gmatch(s, "%*%.(%w+),") do
t[k] = ft
end
end
local lf = require("largefiles")
local ext = {
dockerfile = "dockerfile",
automount = "systemd",
mount = "systemd",
path = "systemd",
service = "systemd",
socket = "systemd",
swap = "systemd",
target = "systemd",
timer = "systemd",
log = "log",
LOG = "log",
_log = "log",
_LOG = "log",
scpt = "applescript",
applescript = "applescript",
Caddyfile = "caddyfile",
csv = "csv",
tsv = "csv",
tab = "csv",
dat = "csv",
mako = "mako",
dbml = "dbml",
lalrpop = "lalrpop",
snippets = "snippets",
jinja = "jinja",
jinja2 = "jinja",
j2 = "jinja",
http = "http",
tmpl = "gotmpl",
gotmpl = "gotmpl",
}
vim2ext(ext, "*.vert,*.tesc,*.tese,*.glsl,*.geom,*.frag,*.comp,*.rgen,*.rmiss,*.rchit,*.rahit,*.rint,*.rcall", "glsl")
vim2ext(ext, "*.vs,*.fs", "glsl")
vim2ext(ext, "*.graphql,*.graphqls,*.gql,*.prisma", "graphql")
vim2ext(ext, "*.gotmpl,helmfile*.yaml", "yaml.helm")
vim.filetype.add({
extension = ext,
pattern = {
["openapi.*%.ya?ml"] = "yaml.openapi",
["openapi.*%.json"] = "json.openapi",
["*%.snip"] = "vim",
["*%.nginx"] = "nginx",
[".*nginx.*%.conf"] = "nginx",
[".*nginx/.*/conf.*"] = "nginx",
[".*/nginx/.*%.conf"] = "nginx",
["/srv/nginx/conf%.d/locations/.*"] = "nginx",
[".*/playbooks/*.y*"] = "yaml.ansible",
[".*compose.*.y*"] = "yaml.docker-compose",
["Caddyfile.*"] = "caddyfile",
["haproxy.*.c.*"] = "haproxy",
[".*/templates/.*.yaml"] = "yaml.helm",
[".*/templates/.*.tpl"] = "yaml.helm",
[".*/helm/.*.yaml"] = "yaml.helm",
[".*"] = {
function(path, buf)
lf.optimize_buffer(buf, path)
local t = lf.is_large_file(buf, false, path)
if t == lf.FILE_TYPE.LARGE_SIZE then
return "largefile.size"
end
if t == lf.FILE_TYPE.READ_ONLY then
return "largefile.readonly"
end
return nil
end,
},
},
})

200
nvim/init.lua Normal file
View file

@ -0,0 +1,200 @@
vim.loader.enable()
table.unpack = table.unpack or unpack
if not vim.uv then
vim.uv = vim.loop
end
local g = vim.g
local opt = vim.opt
g.has_ui = #vim.api.nvim_list_uis() > 0
g.modern_ui = (g.has_ui and vim.env.DISPLAY ~= nil) or string.format("%s", vim.env.TERM):find("256")
g.post_load_events = { "BufReadPost", "FileReadPost", "TermOpen" }
g.pre_load_events = { "BufReadPre", "FileReadPre", "BufNewFile", "TermOpen" }
-- stylua: ignore start
g.snips_author = vim.env.AUTHOR or "Jury Markin"
g.snips_email = vim.env.EMAIL or "me@jmarkin.ru"
g.snips_github = vim.env.GITHUB or "https://github.com/JMarkin"
opt.cmdheight = 0
-- opt.colorcolumn = '+1'
opt.cursorlineopt = 'both'
opt.cursorline = true
-- g.cursorhold_updatetime = 200
g.default_winwidth = 20
g.default_winheight = 1
opt.winwidth = g.default_winwidth
opt.winheight = g.default_winheight
opt.winminwidth = 20
opt.pumheight = 20
opt.splitright = true
opt.splitbelow = true
opt.equalalways = false
opt.updatetime = 200
opt.number = true
g.numbertoggle = true
opt.ruler = true
opt.scrolloff = 4
opt.sidescrolloff = 8
opt.sidescroll = 0
opt.signcolumn = 'yes:1'
opt.swapfile = true
opt.undofile = true
opt.wrap = false
opt.linebreak = true
opt.breakindent = true
opt.scrollback = 2000
opt.conceallevel = 0
opt.autowriteall = true
opt.virtualedit = 'block'
opt.mouse = "vh"
opt.mousemoveevent = true
opt.mousefocus = false
g.mapleader = "\\"
opt.fileencoding = "utf-8"
opt.encoding = "utf-8"
opt.hidden = true
opt.showmatch = false
opt.hlsearch = true
opt.autochdir = false
opt.bs = "indent,eol,start"
g.editorconfig = true
opt.synmaxcol = 240
opt.exrc = true
opt.laststatus = 3
opt.guifont = "JetBrainsMonoNL Nerd Font Mono:h13"
opt.guicursor = "a:block"
opt.background = "dark"
if vim.fn.has('nvim-0.11') == 1 then
opt.completeopt = "menu,menuone,noselect,popup,noinsert,fuzzy"
else
opt.completeopt = "menu,menuone,noselect,popup,noinsert"
end
opt.cia = 'kind,abbr,menu'
opt.tags = { "tags", ".git/tags" }
opt.spell = false
opt.spelllang = { "en", "ru" }
g.spellfile_URL = "https://ftp.nluug.nl/vim/runtime/spell/"
g.root_pattern = {
".nvim.lua",
"flake.nix",
"Makefile",
".git",
}
opt.list = true
opt.listchars = {
tab = '',
trail = '·',
eol = '',
}
opt.fillchars = {
eob = ' ',
}
opt.tabstop = 4
opt.softtabstop = 4
opt.shiftwidth = 4
opt.expandtab = true
opt.smartindent = true
opt.autoindent = true
opt.ignorecase = true
opt.smartcase = true
opt.termguicolors = true
opt.textwidth = 80
opt.relativenumber = true
opt.sessionoptions = 'curdir,folds,globals,help,tabpages,terminal,winsize'
opt.viewoptions = 'folds,cursor'
g.omni_sql_ignorecase = 1
g.lsp_autostart = vim.env.LSP_AUTOSTART ~= nil
opt.wildignore:append({ -- Ignore on file name completion.
".DS_store",
"**/node_modules/**",
"**/.venv/**",
})
opt.lazyredraw = true
-- stylua: ignore end
g.dbs = {
{ name = "local", url = vim.env.DB_URL },
}
opt.shortmess:append({ W = false, I = true, c = true, C = true, A = false })
if g.modern_ui then
opt.listchars:append({ nbsp = "" })
opt.fillchars:append({
eob = " ",
diff = "",
})
-- vim.api.nvim_command('colorscheme ex-bamboo')
else
opt.termguicolors = false
end
opt.backup = true
opt.backupdir:remove(".")
-- netrw settings
-- stylua: ignore start
g.netrw_winsize = 30
g.netrw_banner = 0
g.netrw_cursor = 5
g.netrw_keepdir = 1
g.netrw_list_hide = "__pycache__," .. [[\(^\|\s\s\)\zs\.\S\+]]
g.netrw_liststyle = 0
g.netrw_localcopydircmd = "cp -r"
g.netrw_localmkdir = "mkdir -p"
g.netrw_preview = 1
g.netrw_alto = 1
g.netrw_fastbrowse = 2
g.netrw_sizestyle = "H"
g.netrw_sort_options = "i"
-- stylua: ignore end
-- disable plugins shipped with neovim
-- g.loaded_2html_plugin = 1
g.loaded_matchit = 1
g.loaded_tutor_mode_plugin = 1
g.loaded_vimball = 1
g.loaded_vimballPlugin = 1
g.loaded_python3_provider = 1
g.loaded_ruby_provider = 1
g.loaded_node_provider = 1
g.loaded_perl_provider = 1
-- g.loaded_zip = 1
-- g.loaded_zipPlugin = 1
-- g.loaded_gzip = 1
-- g.loaded_tar = 1
-- g.loaded_tarPlugin = 1
-- stylua: ignore end
vim.g.rainbow_delimiters_highlight = {
"RainbowDelimiterRed",
"RainbowDelimiterYellow",
"RainbowDelimiterBlue",
"RainbowDelimiterOrange",
"RainbowDelimiterGreen",
"RainbowDelimiterViolet",
"RainbowDelimiterCyan",
}

63
nvim/lsp/basedpyright.lua Normal file
View file

@ -0,0 +1,63 @@
local function set_python_path(path)
local clients = vim.lsp.get_clients({
bufnr = vim.api.nvim_get_current_buf(),
name = "basedpyright",
})
for _, client in ipairs(clients) do
if client.settings then
client.settings.python = vim.tbl_deep_extend("force", client.settings.python or {}, { pythonPath = path })
else
client.config.settings = vim.tbl_deep_extend("force", client.config.settings, { python = { pythonPath = path } })
end
client.notify("workspace/didChangeConfiguration", { settings = nil })
end
end
return {
cmd = { "basedpyright-langserver", "--stdio" },
filetypes = { "python" },
root_markers = {
"pyproject.toml",
"setup.py",
"setup.cfg",
"requirements.txt",
"Pipfile",
"pyrightconfig.json",
".git",
},
settings = {
basedpyright = {
analysis = {
autoSearchPaths = true,
typeCheckingMode = "off",
useLibraryCodeForTypes = true,
diagnosticMode = "openFilesOnly",
exclude = {
"node_modules",
"**/__pycache__",
"tests",
"build",
"dist",
".*",
"**/.*",
},
},
},
},
on_attach = function(client, bufnr)
vim.api.nvim_buf_create_user_command(bufnr, "LspPyrightOrganizeImports", function()
client:exec_cmd({
command = "basedpyright.organizeimports",
arguments = { vim.uri_from_bufnr(bufnr) },
})
end, {
desc = "Organize Imports",
})
vim.api.nvim_buf_create_user_command(0, "LspPyrightSetPythonPath", set_python_path, {
desc = "Reconfigure basedpyright with the provided python path",
nargs = 1,
complete = "file",
})
end,
}

3
nvim/lsp/clangd.lua Normal file
View file

@ -0,0 +1,3 @@
return {
cmd = { "clangd", "--background-index=false", "--clang-tidy" },
}

View file

@ -0,0 +1,10 @@
return {
cmd = { "docker-language-server start", "--stdio" },
filetypes = { "dockerfile", "yaml.docker-compose" },
root_markers = { "Dockerfile", "docker-compose.yaml", "docker-compose.yml", "compose.yaml", "compose.yml" },
settings = {
initializationOptions = {
telemetry = "off",
},
},
}

37
nvim/lsp/gopls.lua Normal file
View file

@ -0,0 +1,37 @@
return {
settings = {
gopls = {
gofumpt = false,
codelenses = {
gc_details = false,
generate = true,
regenerate_cgo = true,
run_govulncheck = true,
test = true,
tidy = true,
upgrade_dependency = true,
vendor = true,
},
hints = {
assignVariableTypes = true,
compositeLiteralFields = true,
compositeLiteralTypes = true,
constantValues = true,
functionTypeParameters = true,
parameterNames = true,
rangeVariableTypes = true,
},
analyses = {
nilness = true,
unusedparams = true,
unusedwrite = true,
useany = true,
},
usePlaceholders = true,
completeUnimported = true,
staticcheck = true,
directoryFilters = { "-.git", "-.vscode", "-.idea", "-.vscode-test", "-node_modules" },
semanticTokens = false,
},
},
}

8
nvim/lsp/jsonls.lua Normal file
View file

@ -0,0 +1,8 @@
return {
settings = {
json = {
schemas = require("schemastore").json.schemas(),
validate = { enable = true },
},
},
}

38
nvim/lsp/lua_ls.lua Normal file
View file

@ -0,0 +1,38 @@
return {
settings = {
Lua = {
telemetry = {
enable = false,
},
hint = {
enable = true,
},
runtime = {
version = "LuaJIT",
},
diagnostics = {
globals = {
"vim",
},
},
completion = {
callSnippet = "Replace",
},
workspace = {
checkThirdParty = false,
library = {
[vim.fn.expand("$VIMRUNTIME/lua")] = true,
[vim.fn.expand("$VIM/lazy")] = true,
[vim.fn.expand("$VIMRUNTIME")] = true,
[vim.fn.expand("~/.config/nvim/lua")] = true,
},
},
},
},
on_attach = function(client, buf)
if vim.bo[buf].filetype == "lua" and vim.api.nvim_buf_get_name(buf):find("_spec") then
vim.diagnostic.enable(false, { bufnr = buf })
return
end
end,
}

View file

@ -0,0 +1,38 @@
return {
settings = {
checkOnSave = true,
completion = {
autoimport = {
enable = false,
},
},
procMacro = {
enable = true,
},
files = {
excludeDirs = {
".direnv",
"_build",
".dart_tool",
".flatpak-builder",
".git",
".gitlab",
".gitlab-ci",
".gradle",
".idea",
".next",
".project",
".scannerwork",
".settings",
".venv",
"archetype-resources",
"bin",
"hooks",
"node_modules",
"po",
"screenshots",
"target",
},
},
},
}

5
nvim/lsp/ty.lua Normal file
View file

@ -0,0 +1,5 @@
return {
cmd = { "ty", "server" },
filetypes = { "python" },
root_dir = vim.fs.root(0, { ".git/", "pyproject.toml" }),
}

16
nvim/lsp/yamlls.lua Normal file
View file

@ -0,0 +1,16 @@
return {
filetypes = { "yaml", "yaml.openapi", "yaml.helm", "yaml.ansible" },
settings = {
yaml = {
schemaStore = {
enable = false,
},
schemas = require("schemastore").yaml.schemas(),
},
redhat = {
telemetry = {
enabled = false,
},
},
},
}

462
nvim/lua/banner.lua Normal file
View file

@ -0,0 +1,462 @@
local M = {
["datetime"] = {
"Today's " .. os.date("%a %d %b"),
-- os.date " %m-%d-%Y  %H:%M:%S",
},
["threeskulls"] = {
[[⠀⠀⠀⠀⠀⣀⣀⣤⣤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⣤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣤⣤⣀⣀⠀⠀⠀⠀⠀]],
[[⠀⠀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⣶⣄⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀]],
[[⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀]],
[[⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣿⣿⣿⡆⠀⠀⠀⢸⣿⣿⠿⠿⢿⣿⣿⣿⣿⡿⠿⠿⣿⣿⡇⠀⠀⠀⣾⣿⣿⡿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆]],
[[⢿⣿⠿⠿⠿⠿⣿⣿⣿⡏⠀⠀⠀⢹⣿⡇⠀⠀⠀⢸⣿⢱⣶⣴⣶⢹⣿⣿⡏⣶⣦⣶⡎⣿⡇⠀⠀⠀⢿⣿⠁⠀⠀⠈⣿⣿⣿⡿⠟⣋⣽⣿⣿⠇]],
[[⠘⣿⣧⣄⣀⣴⣿⣿⣿⣷⣄⣀⣠⣾⣟⠀⠀⠀⠀⠈⣿⣦⣙⣛⣡⣾⡿⢿⣷⣌⣛⣋⣴⣿⠁⠀⠀⠀⠘⣿⣦⣄⣀⣴⣿⣿⣿⣿⣶⣶⣤⣿⡟⠀]],
[[⠀⢿⣿⣿⣿⣿⣏⣼⣌⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣰⣆⣿⣿⣿⣿⣿⡿⠀⠀⠀⠀⠈⢿⣿⣿⣿⣿⣏⣼⣌⣿⣿⣿⣿⣿⠏⠀]],
[[⠀⠀⠉⠉⢿⣿⣿⣿⣿⣿⣿⡏⠉⠁⠀⠀⠀⠀⠀⠀⠀⠉⠉⢹⣿⣿⣿⣿⣿⣿⡏⠉⠉⠀⠀⠀⠀⠀⠀⠀⠉⠉⣿⣿⣿⣿⣿⣿⣿⡏⠉⠁⠀⠀]],
[[⠀⠀⠀⠀⠈⠉⠁⠁⠁⠉⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠁⠉⠉⠈⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠁⠁⠁⠉⠉⠀⠀⠀⠀⠀]],
},
["nvim1"] = {
[[ __ ]],
[[ ___ ___ ___ __ __ /\_\ ___ ___ ]],
[[ / _ `\ / __`\ / __`\/\ \/\ \\/\ \ / __` __`\ ]],
[[/\ \/\ \/\ __//\ \_\ \ \ \_/ |\ \ \/\ \/\ \/\ \ ]],
[[\ \_\ \_\ \____\ \____/\ \___/ \ \_\ \_\ \_\ \_\]],
[[ \/_/\/_/\/____/\/___/ \/__/ \/_/\/_/\/_/\/_/]],
},
["nvim2"] = {
[[ _/ _/ _/ _/ _/ ]],
[[ _/_/ _/ _/_/ _/_/ _/ _/ _/_/_/ _/_/ ]],
[[ _/ _/ _/ _/_/_/_/ _/ _/ _/ _/ _/ _/ _/ _/]],
[[ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ ]],
[[_/ _/ _/_/_/ _/_/ _/ _/ _/ _/ _/ ]],
},
["nvim4"] = {
[[  ]],
[[ ████ ██████ █████ ██ ]],
[[ ███████████ █████  ]],
[[ █████████ ███████████████████ ███ ███████████ ]],
[[ █████████ ███ █████████████ █████ ██████████████ ]],
[[ █████████ ██████████ █████████ █████ █████ ████ █████ ]],
[[ ███████████ ███ ███ █████████ █████ █████ ████ █████ ]],
[[██████ █████████████████████ ████ █████ █████ ████ ██████]],
},
["nvim5"] = {
[[ ]],
[[ ██████ █████ █████ █████ ███ ]],
[[ ░░██████ ░░███ ░░███ ░░███ ░░░ ]],
[[ ░███░███ ░███ ██████ ██████ ░███ ░███ ████ █████████████ ]],
[[ ░███░░███░███ ███░░███ ███░░███ ░███ ░███ ░░███ ░░███░░███░░███ ]],
[[ ░███ ░░██████ ░███████ ░███ ░███ ░░███ ███ ░███ ░███ ░███ ░███ ]],
[[ ░███ ░░█████ ░███░░░ ░███ ░███ ░░░█████░ ░███ ░███ ░███ ░███ ]],
[[ █████ ░░█████░░██████ ░░██████ ░░███ █████ █████░███ █████ ]],
[[ ░░░░░ ░░░░░ ░░░░░░ ░░░░░░ ░░░ ░░░░░ ░░░░░ ░░░ ░░░░░ ]],
[[ ]],
},
}
M.nami = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢀⣀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢀⠠⠄⠀⠀⠈⠀⠀⠀⠀⠀⠀⠊⠨⠀⢄⠀⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣄⠔⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠀⠈⠻⣿⣿⣿⣿⣿⣿⣿",
"⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠆⠂⠀⠀⠀⠀⠀⣠⣄⢰⡆⢷⡘⣷⡆⢦⠰⣄⢠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣿⣿",
"⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠂⠉⠀⠀⠀⠀⠀⣰⢃⣾⣿⣿⡌⢷⠸⣷⡘⣿⡌⢇⢻⡄⢿⣎⢲⣄⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⣿⣿",
"⠀⠀⠀⠀⠀⠀⠀⠀⡠⠋⠀⠀⠀⠀⣠⡄⣼⢠⠃⣾⣿⣿⣿⣷⡘⡆⢻⣷⡌⢿⡌⠀⢿⡘⣿⡆⠿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿",
"⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⣠⢀⣿⢠⡇⡎⣼⣿⣿⣿⣿⣿⣷⡔⠘⣿⣿⣦⠻⡌⠈⢷⡘⣷⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿",
"⡇⠀⠀⠀⢀⠈⠁⠀⠀⠀⠀⣸⣿⢸⡏⠸⠐⢰⣿⣿⣿⣿⣿⣿⣿⣿⣦⣘⣿⣿⣷⣄⠀⠀⢳⡘⡆⠈⣿⠰⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹",
"⣇⠀⠀⡠⠂⠀⠀⠀⠀⢠⢁⣿⣿⢸⡇⡆⢀⠿⠿⠿⠛⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣂⡀⠀⢳⠠⠀⣿⡀⡆⠀⠀⠀⠀⠀⠀⠀⠀⣼",
"⣿⠀⠀⠀⠀⠀⠀⠀⢀⠎⣼⡟⠠⢸⡇⠀⣰⣶⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⢋⣵⣿⣿⣷⣦⠀⠁⠀⣿⡇⠇⠀⠀⠀⠀⠀⠀⠀⣰⣿",
"⣿⠁⠀⠀⠀⠀⠀⠀⠌⣼⠟⢀⠀⠀⡇⡆⣿⡿⠋⠉⠉⠡⢿⣿⣿⣿⣿⣿⠃⣾⡿⠋⠉⠠⠍⠡⠵⡀⣿⡇⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿",
"⠃⠀⠀⠀⠀⠀⠀⢀⠚⡣⢠⢊⠀⡄⠀⠗⣠⠘⠁⢀⣀⣈⣹⣿⣿⣿⣿⣿⢸⣿⠎⣀⣤⣤⡀⢁⣶⡇⣿⡇⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿",
"⠀⠀⠀⠀⠀⠀⠀⡿⢡⡀⢡⢇⠀⣷⡀⡾⠁⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠿⣿⣿⣿⣿⣿⣿⣿⠀⣿⠁⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿",
"⠀⠀⠀⠀⠀⠀⠀⡇⢸⢨⠂⡸⠀⢹⣿⣷⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢃⣴⣿⣿⣿⣿⣿⣿⡇⢠⡏⠀⣀⣴⣿⣿⣿⣿⣿⣿⣿⣿",
"⠀⠀⠀⠀⠀⠀⠀⠁⠘⣆⠃⠱⡀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡷⠿⠿⠿⢿⣿⣿⣿⣿⠀⡼⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⠀⠀⠀⠀⠀⠀⠀⠀⠠⡹⣄⡃⠉⢄⠘⣿⣿⣿⣿⣿⣿⣆⠠⢤⣤⣴⠶⠶⠒⠛⢀⣿⣿⣿⣿⠇⣸⠃⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣧⡀⠀⠀⠀⠀⠀⠀⠀⠈⠢⢍⣑⠒⠄⠘⢿⣿⣿⣿⣿⣿⣷⣄⠠⢤⣤⣤⠀⣠⣿⣿⣿⡿⠋⢠⠃⢠⣄⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣦⣀⡀⠀⠀⠀⠀⠀⠀⠐⠨⢅⡚⡀⢤⠙⠻⢿⣿⣿⣿⣿⣿⡶⠤⠤⢊⣿⣿⡿⠛⠁⢀⠂⠀⠲⣌⠳⣦⣈⠛⢿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣍⡈⠀⠀⠀⠈⠉⠛⠛⠿⠿⣿⣿⠿⠟⠋⠀⠀⡠⠁⡀⡄⣷⣌⢳⣌⠻⣿⣦⣄⡉⠫⠯⠉⠍",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⣋⣥⠖⠂⠀⠀⢦⣀⠀⠠⠁⠀⠀⠀⠀⠀⠀⠀⣰⠄⢐⠳⡐⠘⠿⠢⠙⢷⠙⣿⣿⣿⣦⡙⢧⣴",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣫⣴⡿⠋⣱⣿⠃⡇⠀⠈⣿⣧⣤⣤⡀⠀⠀⠀⣄⠆⡼⠋⣼⣿⣷⣤⣴⣿⣿⡗⠀⢇⠙⢿⣿⣿⣿⡆⢻",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⣴⣿⢏⠄⣴⣿⡟⡘⠐⡀⣄⢸⣿⣿⣿⣿⣿⡶⠀⢃⡾⠱⢀⣿⣿⣿⣿⣿⣿⠏⣴⡄⡌⣆⠈⢿⣿⣿⣿⠈",
"⣿⣿⣿⣿⣿⣿⣿⣿⠃⣾⣿⢣⠎⣼⣿⡿⠀⠀⠐⠰⠿⢸⣿⣿⣿⡿⢋⣶⣿⣶⣤⣴⣿⡿⠛⠛⠋⠉⠁⠨⣽⣇⠰⢸⡄⠘⣿⣿⡿⠀",
"⣿⣿⣿⣿⣿⣿⣿⠃⣼⣿⠃⠎⣼⣿⠟⢀⡾⢠⣴⠿⠃⢸⣿⣿⣿⡀⠻⣿⣿⣿⡿⠟⠉⣠⣶⣶⣾⣷⣶⣄⡀⠙⠀⡘⡇⡇⣿⡿⣡⢱",
"⣿⣿⣿⣿⣿⣿⡏⢰⣿⣿⠀⢸⣿⠏⣴⣿⣷⡆⠁⠀⠀⣿⣿⣿⡿⢃⣼⣿⡿⠋⠄⣡⣾⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠌⢀⠀⡿⢡⡟⣿",
"⣿⣿⣿⣿⣿⡿⢁⢸⣿⣿⡆⢈⢻⠸⢛⣉⣩⠂⠀⠀⣴⣿⣿⣿⡦⢸⡿⡋⠈⠌⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠉⢸⡇⣿⢹⣿",
"⣿⣿⣿⣿⣿⢱⢃⡄⢻⣿⣿⠈⡆⠃⢾⣿⡏⠀⠀⣼⣿⣿⠟⣫⡴⢋⠀⡃⠈⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠄⣿⡅⣿⠸⣿",
}
M.luffy = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⢟⣛⣛⣛⣉⣉⣉⣙⣛⣛⣛⠻⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⢋⣥⣶⡿⠟⠅⡿⠿⠿⠾⠿⠿⠍⠛⠋⢿⣶⣦⣍⡻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠡⠾⢟⣋⣀⣠⣤⣴⣶⣶⣶⣾⣿⣷⣶⣶⣶⣬⣁⣉⣙⠻⠦⣉⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⢟⣡⣴⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢿⣿⣿⣿⣿⣶⣦⣀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⢛⣡⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠛⢉⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣉⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⣡⡾⠟⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠉⠁⠀⠀⠀⠀⠀⠴⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢋⣤⡞⡣⢐⣾⣿⣿⣿⣿⣿⣿⡿⠟⠋⠀⠀⠀⢠⣦⠀⠀⠀⠀⡀⠀⠀⠀⠉⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢟⢳⡌⠻⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢋⣴⠟⡡⢪⢜⡯⣿⣿⢉⡭⢛⠟⠋⠀⠀⠀⣠⣾⠀⣿⣿⣆⠀⠀⠀⢱⣄⠀⠀⠀⠀⠀⠙⠿⣿⢿⡛⢿⡛⣿⢷⡘⡦⣦⢹⣦⠘⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⡿⢡⣾⢋⣼⣼⡵⣡⣪⠟⢁⣤⠒⠁⠀⠀⠀⢀⣼⣿⣿⠀⣿⣿⣿⣦⠀⠀⠈⣿⣧⡀⠀⠀⠀⠀⠀⠈⠳⢝⢂⠋⢻⡁⡐⡐⣙⣦⡍⣷⡈⢿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⡟⢀⣿⣿⣿⣿⣿⡟⣱⠟⣠⣿⠁⠀⠀⠀⡄⢀⣾⣿⣿⣿⡄⣿⣿⣿⣿⣷⣄⠀⢹⣿⣿⡄⠀⢠⠀⠀⠀⠀⠀⠀⠁⠡⢴⣴⣾⣿⣿⣿⣿⣿⡄⢻⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⡿⢠⣿⣿⣿⣿⣿⣿⠖⣧⣎⣾⠁⠀⠀⢀⡜⠠⠟⠛⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠈⠛⣻⣭⣄⠀⣧⠀⠀⠀⠹⣷⠳⡄⠘⠟⢻⣿⣿⣿⣿⣿⣿⡄⢻⣿⣿⣿",
"⣿⣿⣿⣿⣿⡿⢠⡟⡸⠻⠛⠹⣿⡟⠸⣿⣿⠁⠀⠀⠀⣼⢃⣾⣿⣿⣿⣷⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣦⢹⡆⠀⠀⠀⠹⠓⠸⡄⠜⠇⠆⠉⣿⣿⣿⣿⣿⠈⣿⣿⣿",
"⣿⣿⣿⣿⡿⠀⡿⢀⠁⠃⠇⡆⢻⢰⢰⡆⢁⡀⠀⠀⣰⣿⣿⣿⡿⠿⢿⣿⣿⣿⣿⣧⠹⣿⣿⣿⣿⣿⡿⠟⠛⠙⠛⢿⣿⠀⠀⠀⠀⠀⢄⠰⣴⣸⡘⣴⡌⣿⣧⣿⣿⠀⣿⣿⣿",
"⣿⣿⣿⣿⠀⢸⠀⡇⡎⡆⡆⡇⡈⡈⠚⣠⣿⣿⠀⠀⣿⣿⡿⠃⣠⣤⣤⡀⢙⣿⣿⣟⠀⢻⣿⣿⣿⣿⢠⣶⣿⣷⣄⠘⣿⡆⠃⠀⢹⣿⣾⣧⡈⠁⠃⢸⢸⣷⡍⡿⣿⠀⣿⣿⣿",
"⣿⣿⣿⣿⡀⢸⠀⡇⡇⡇⡇⣇⠁⣶⣾⣿⣿⣿⡆⢰⣿⣿⠃⣼⣿⣿⣿⣿⣿⣿⣿⣿⢀⡞⢿⣿⣿⣿⣏⠛⠟⠻⠟⠛⠛⢿⣼⢠⣼⣿⣿⣿⣧⠀⠆⠘⠌⡏⠇⣇⣿⠆⣿⣿⣿",
"⣿⣿⣿⣿⡇⢸⡆⡇⡇⠁⡡⢸⠁⣹⣿⣿⣿⣿⣿⠘⠟⠉⠙⣻⣿⣿⣿⡿⠿⠿⠟⣛⣛⣛⣛⣛⣛⣛⣛⣛⠷⠼⠿⣶⣶⣀⠉⢰⣿⣿⣿⣿⡟⠀⡼⠠⠠⠠⡠⡸⢿⢠⣿⣿⣿",
"⣿⣿⣿⣿⣷⠘⣧⢹⠘⠀⣁⣡⡁⣿⣿⣿⣿⣿⣿⡆⢴⣶⠻⠟⡋⢩⣵⣶⣶⣿⣿⣿⣿⠿⠿⠿⢿⣿⣿⣿⣿⣷⣄⣬⠙⣿⠂⢍⢿⣿⣿⣿⠏⣸⡷⠠⢁⠁⠁⢠⠁⣾⣿⣿⣿",
"⣿⣿⣿⣿⣿⠀⢿⢠⠡⠁⡹⢠⡄⢸⣿⣿⣿⣿⣿⣏⠘⣿⡆⢼⣿⣿⣿⡿⠟⠉⠉⠀⠀⠀⠀⠀⠀⠀⠉⠉⠙⠿⠿⡿⢠⣿⢠⣆⠼⠛⠉⣡⣈⠓⢰⣠⠋⠔⣱⢋⣼⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣧⠘⢄⢢⠁⡑⢦⡙⢸⣿⣿⣿⣿⡿⣿⡁⢹⣷⡘⠿⠟⠁⠀⢠⣂⣴⣿⣿⣶⣶⣾⣿⣦⣄⣀⠀⠀⠉⣡⣿⠃⠞⣁⣀⣴⣶⣎⠛⣷⣄⢱⣠⡾⢋⣾⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣶⡈⢾⣦⣹⣾⣷⡈⠻⣿⣿⣿⣿⣿⠟⡂⢿⣿⣆⡀⢰⡾⠿⠿⠿⣛⣛⣛⣛⣛⣛⣛⡻⠿⡧⢀⡴⠿⠿⠈⣾⣿⣿⣿⣿⣿⢣⢸⡏⠈⢋⣴⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣦⡙⠿⣿⣏⡱⠄⠻⣿⣷⢿⠽⣷⠙⠆⢻⣿⣷⣆⣀⠲⠿⣿⣿⣿⣿⣿⣿⣿⠿⠿⣃⣴⡞⢰⣶⠦⢐⣠⣿⣿⣿⣿⠏⠀⠈⣴⠀⣤⠙⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣬⡑⠿⡿⢷⣌⠻⣍⣶⠞⠗⡆⠀⠉⠻⠿⢿⣷⣶⣦⣭⣭⣭⣭⣭⣶⣶⣾⣟⠉⠰⢻⣿⣷⣿⣿⣿⡿⢿⣿⡂⠆⠀⢿⣦⠹⣃⣉⢿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⡮⠭⠉⠗⣈⡑⠀⠈⠁⠄⢀⣠⡀⡐⠈⠉⠙⠛⠿⠿⠿⠟⠛⡉⠉⡀⠂⠀⠘⠿⠿⠿⢛⣥⣶⣦⣉⣙⢳⡿⢆⣹⠃⣿⣿⡄⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣋⣩⣴⣾⣶⣿⣿⣿⣾⣿⣿⣦⣀⡈⠀⣿⣷⣄⠀⠀⠀⢀⡆⠀⠀⡆⣰⢱⡠⢀⣉⣁⣤⣾⣿⣿⣿⣿⣿⣿⣮⡳⠿⣀⣀⠿⢛⣡⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⣁⣊⣙⣋⣍⣛⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣙⠻⣿⣷⣤⣀⣿⠃⡄⡠⡇⠃⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣏⣵⣦⣩⣶⣦⡶⠞⢉⠈⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⠟⣡⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣮⣙⠻⣿⣿⡆⢓⣥⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣗⠈⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⠟⣡⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠓⣨⣥⣶⣿⣿⣿⣿⡿⠋⠀⢠⣿⣿⣿⣿⣿⡿⢿⡿⢿⠿⣿⣿⣿⣿⣿⣿⣿⣷⠸⣿⣿⣿",
"⣿⣿⣿⣿⠃⣼⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠛⠛⠋⠛⠛⠿⡏⠳⢿⣦⢇⢹⠇⣸⣿⣿⣿⣿⠟⢛⣛⠁⠀⣴⣶⣿⣿⣿⠟⣡⠂⢀⣡⣞⡻⠿⣿⣿⣿⣿⣿⣩⠛⣿⠀⣿⣿⣿",
"⣿⣿⣿⣿⡆⣿⡙⢿⡙⣟⠋⠃⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠃⠊⠦⣠⣾⣿⣿⡟⠀⢀⣿⣿⣿⣿⠟⠫⠍⠛⠁⠒⠀⠀⠊⠥⠴⠅⠒⠁⢤⡴⢟⠋⣁⠙⠥⠔⢰⣿⣿⣿",
"⣿⣿⣿⣿⣇⠻⡙⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣷⣶⣿⡟⡿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠛⠋⡀⣼⣿⣿⣿",
"⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠋⠿⡘⣿⠸⠈⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⢿⣿⣿",
"⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⢠⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣤⣄⣀⠀⠀⠀⣀⣠⣤⣄⡀⠀⣠⣤⣤⣴⣦⣤⣶⣶⣶⣤⣤⣤⣤⣤⣤⡄⢠⣴⡦⠀⠀⠀⠀⠀⠀⠈⢻⣿",
"⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠘⣿⣿⣇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢰⣿⣿⣿⣿⣿⣿⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢣⣾⡟⣀⣠⣤⣤⣤⣀⡀⠀⠈⢿",
"⣿⣿⡏⠀⠀⣠⣴⣾⣿⣿⣷⣌⢻⣿⢸⡏⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠘⣿⣿⣿⣿⣿⣿⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⣸⡟⣰⣿⣿⣿⣿⣿⣿⣿⣿⣶⡌",
"⣿⡏⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⡎⢿⣾⡇⣼⣿⣿⡿⠿⠟⠛⠛⠛⠋⠉⠙⠛⠀⠛⠛⠛⠛⠛⠛⠸⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠻⠿⣿⠇⣿⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧",
"⡟⢱⣿⡿⠿⠿⠿⠿⠿⠿⣿⣿⣷⠸⠈⠐⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠉⠈⠛⠻⢿⣿⣿⣿⡿⠿⠿⠿",
}
M.zoro = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣿⣿⣿⣿⣿⣿⡿⠟⠉⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠈⠼⢛⣩⣀⣨⣥⣶⣏⣀⠹⣿⣿⣿⡿⠟⢉⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⢸⣿⠟⠁⠼⣋⣴⣾⣾⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣤⣬⣀⠀⠛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠟⣡⡆⠘⣡⣤⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣖⣀⢠⣍⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠸⡟⠀⣠⣿⣯⣾⣿⣿⣿⣿⣿⣿⡿⡿⢋⣴⣿⡿⢿⡿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣤⣤⡈⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⢰⣧⢀⣾⣿⣿⣿⣿⣿⣿⣿⣶⢐⠏⡜⢰⠟⣿⠟⡴⢋⣴⡿⢛⣽⣿⣿⣿⣿⣿⠛⣩⣿⣿⣿⣿⣿⣏⠐⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⢂⣿⣿⣿⣿⢿⡿⢸⣿⡿⢿⡟⡋⡿⢿⡿⢡⠆⣯⣼⣱⡟⠋⢀⣥⡾⠿⢿⣿⡟⣋⡾⢋⣽⣿⣿⣿⣿⣿⣧⡈⠻⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⣠⣾⣿⣿⣿⣿⡎⣰⡼⣿⣿⡌⢰⡇⠁⢸⠀⠛⢐⡉⣹⣿⡏⢀⡿⢁⠀⣴⣿⣿⠋⡩⢐⣽⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⢸⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⣘⠈⣻⡟⣿⡟⢹⡿⢁⠙⠀⠿⣿⠇⠘⢡⠇⡄⢂⣾⠟⠸⢟⣫⡖⢈⡴⢃⣈⣿⡷⢐⣣⠖⣘⡽⣛⣿⣿⣛⠟⣛⣻⣿⣿⣿⠦⠙⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⣿⣿⣿⢡⠸⢣⠸⡇⣾⠀⣷⢠⡏⣤⢴⠟⢛⣡⣌⡉⠈⠛⠦⡉⣬⣭⣴⣶⣶⣤⣭⣭⣙⣛⠻⢟⣻⣯⣿⠟⢛⠟⣋⣿⣿⡦⠄⢛⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠘⣿⠿⣇⠃⠸⣦⣇⠹⡦⠥⠿⠃⣈⡂⠨⣄⠙⣿⣿⣷⣮⣥⣦⡈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡘⢯⡭⢀⣼⠟⣚⣿⡿⣿⣄⠀⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⢉⡛⠀⢿⣄⡀⢀⡑⠆⣉⣴⣶⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⡇⠀⣤⣶⠾⠿⢟⣑⣊⠽⣿⣷⣌⠻⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⡌⣿⣿⣧⠹⡇⢠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡙⢿⣿⣿⣿⠘⣷⡐⠾⣭⣍⣉⡴⢊⣭⣄⠲⢾⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠠⣸⣿⡇⠣⡁⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣯⢻⣿⣿⣿⣿⣿⣿⡿⢿⣿⡈⠻⣿⣿⡇⢻⠭⢅⠨⢛⣛⣷⣿⣿⡇⢸⣿⣿⣿⠿⠋",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡌⢿⡗⢤⣤⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⢸⢸⣿⣿⡿⣿⣿⣿⣷⡜⣿⣷⣤⣽⣿⡇⢸⣪⡥⢚⣿⣾⣿⡿⢟⠁⠈⠛⠛⠁⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡍⢁⣤⣮⡀⢬⠘⣿⡟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠘⣿⣿⣷⡌⣿⣿⣿⣷⠘⣿⣿⣿⣿⣷⣦⣍⠲⣿⣿⣿⡏⣴⢀⠉⢰⣦⡀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠻⣿⣿⣦⡀⢿⣇⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⢠⣿⣿⣿⡇⠈⣿⣿⣿⣇⠙⣛⣛⠻⢿⣿⣿⣧⠹⡿⠋⣸⢡⢸⡆⣾⣿⣿⣆⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡁⢈⣒⠲⠾⠈⠻⢸⠿⢛⣉⡙⢿⣿⣿⣿⣿⣿⣯⢻⣿⠞⣼⣿⣿⣿⣷⣾⣿⣿⡟⣡⠈⠿⠿⠿⢿⣿⣿⠿⠀⠴⠀⠇⠘⣾⡇⢿⣿⣿⣿⣦⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡦⠙⣥⡀⣿⣧⡴⠎⣁⡙⠿⣿⣿⣿⣿⣿⣿⣿⡈⣯⢰⠘⣿⡿⠿⠟⠛⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡇⡒⠀⠀⡄⡿⠁⢚⣿⣿⣿⣿⡇",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⢸⣧⢹⣯⣴⡿⠿⠿⠶⠬⠍⠙⠛⠛⠛⠿⠇⣿⠨⡑⠈⠀⠀⠀⢀⡤⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⡇⠇⢰⡆⢰⠃⠀⢰⣿⣿⣿⣿⢃",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢀⡙⠌⠃⠀⠀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⡇⠁⠀⠀⠁⠀⠀⢺⣿⣿⣿⡿⣸",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠘⠆⠀⠀⠀⠛⠁⠀⠀⠀⠀⠀⠀⠀⢀⣶⠸⣿⣿⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣿⣿⣿⠁⠀⠀⠀⠀⠐⢦⡍⣹⣿⣿⣇⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢠⠢⡄⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⡀⢿⣿⣿⣿⣿⣷⣦⣤⡤⠄⢀⣂⣀⣙⡛⠿⣿⣿⣿⡀⠀⠀⢠⡘⣦⡱⣶⣿⣿⡟⣸⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⢸⣧⡄⠀⠈⢶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⡇⢸⣿⡿⢿⣿⡿⢛⣩⣶⣿⣿⣿⣿⣿⣿⣶⣌⢻⣿⡇⠀⠀⡆⠱⡌⣣⣿⣿⣿⣇⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⠀⢸⣿⣿⡌⠂⠀⢻⣿⡿⢛⣫⣭⣭⣭⣭⣿⣓⣌⣛⣥⣬⣵⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡘⠁⡄⠀⡇⡆⠀⣽⣿⣿⣿⣍⠻⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⠀⠀⠀⠀⢸⣿⣿⣄⣓⠀⠀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⡿⡿⠟⣿⡿⢿⣿⣿⣿⣿⣶⣤⣀⣁⣁⠸⢛⣿⣿⣿⠿⢓⣸",
"⣿⣿⣿⣿⣿⣿⣿⠟⠋⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⡗⠄⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠉⠉⠉⠉⠻⠙⢷⢀⢌⠂⠻⣌⠂⠢⠙⢟⡻⣿⣿⣿⠿⠋⠀⣾⣿⣿⣷⣦⡍⠹",
"⣿⣿⣿⡿⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⠀⣼⣿⣿⣿⣿⣿⣿⡿⣿⡿⠁⠠⠤⠶⣒⣋⣥⣶⠷⢀⣤⠤⣌⣀⣉⠓⠀⠀⠀⠀⠀⡄⠀⠀⠈⢼⣿⣿⡿⠟⠋⠀⠀",
"⡿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⠏⣴⣿⣿⠋⢹⣏⠇⠻⠇⠟⣁⡐⠒⠛⠛⢛⣋⣩⣤⠶⠛⣡⣴⣿⣿⣿⠏⡀⡀⢸⠀⠀⠁⠀⠀⢐⣿⠟⠁⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢘⠛⢛⣋⣥⠞⡫⢐⠁⠂⡸⠃⠀⠂⠠⣾⣿⣍⠛⠛⣛⣛⣭⣭⣴⣶⣾⣿⣿⣿⡿⠃⠀⠃⠇⠈⠀⢀⠀⠰⢀⣾⡇⠀⠀⠀⠀⢀⣬⣶",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣷⣦⣬⣀⣈⠀⠕⢚⣈⠀⢴⡾⠁⣦⡙⢿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠟⠛⠉⠀⢠⠀⠀⠀⠀⢰⢸⠀⠀⣸⣿⣿⣶⣤⠀⢠⣾⣿⣿",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⢠⣿⣷⣄⠉⠉⢉⣉⡉⠁⠀⠀⠀⠀⢰⠀⠀⡄⠘⠀⠀⣦⠠⡈⠀⠀⣨⣿⣿⣿⡿⣡⣶⣶⣿⣿⡟",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡧⠀⠨⢿⣿⣗⠀⠀⣼⣿⣿⣿⣷⣦⣤⣠⡌⠀⣰⣠⣤⣺⣰⣿⣵⠃⠀⢨⣿⣿⣿⡿⢡⣿⣿⣿⣿⣿⣧",
}
M.robin = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⢛⣫⣭⣭⣭⣛⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣋⣵⣾⣿⣿⡟⣰⣿⣿⣿⣶⣍⡻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢋⣵⣿⣿⣿⣿⣿⣿⢱⣿⣿⣿⣿⣿⣿⣿⣦⡙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣡⣾⣿⣿⣿⣿⣿⣿⣿⠇⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢣⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢡⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⠿⠋⠀⣈⡛⠿⣿⣿⣿⣿⣿⡟⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⢹⣿⣿⣿⡿⠛⠿⠿⢿⡿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⡇⠀⠋⣐⣀⣍⡋⠔⣂⡙⢿⣿⢡⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠿⢿⣿⣿⢡⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠆⢛⣫⡥⠖⡸⢈⣒⡒⠂⠃⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⠀⡷⢸⣿⣿⣿⣿⣶⣬⣙⢠⠥⢘⠻⢿⣿⣿⠿⠿⠿⣛⣛⣛⣛⣒⣒⣒⣒⣒⠢⠭⠭⢍⣉⣙⡛⠛⠛⠿⠿⠟⣋⡅⠙⣨⣴⣶⣷⣶⣿⣿⣷⣶⡌⣆⢻⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⠐⠄⣿⣿⣿⣿⣿⣿⣿⠿⠦⠌⠳⣌⠲⠦⣄⡈⠽⣿⣿⣿⣝⣛⣛⣛⣿⣭⣭⣭⣵⣶⣶⠶⠒⡊⠉⢀⡅⡇⠈⣁⣠⣤⣥⣬⣍⡛⣿⣿⣿⣿⣿⡀⠈⢀⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⡆⢧⢸⣿⣿⣿⣿⡟⣡⣾⣿⣷⡶⠆⠀⠱⣬⡛⠿⢶⣶⣭⣭⣙⣻⣿⠿⠿⣛⣛⣭⣥⣶⡾⢟⢰⡀⠉⠀⠀⠀⠐⢽⣿⣿⣿⣿⣷⠘⣿⣿⣿⣿⡇⡆⣾⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣧⢀⠘⣿⣿⣿⣿⢰⣿⣿⣿⣿⠃⠀⠀⠀⠀⠁⠎⢤⣍⡛⠟⠻⣿⣿⣿⡿⣿⣿⠿⡃⡖⠐⠉⠀⠀⠀⠀⠀⠀⠀⠀⠻⣿⣿⣿⣿⠇⣿⣿⣿⡟⢰⠇⢿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⡆⠃⢻⣿⣿⡏⢸⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠇⠲⠦⠤⢠⡆⡴⠖⠛⠁⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⢠⣿⣿⣿⡧⢐⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣷⡐⡌⣿⣿⣷⢸⣿⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⡏⣼⣿⣿⣿⢃⡇⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠂⠘⣿⣿⠈⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡿⢠⣿⣿⣿⠇⡀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠣⠹⣿⡆⢿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠇⣾⣿⣿⡟⠸⢡⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⢃⠹⣷⠸⡏⠀⠀⠀⠀⠀⠀⠀⠀⡄⠐⠂⠀⠀⡀⠀⠀⠀⣀⢀⠀⠀⠀⡀⠐⠂⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢰⣿⣿⡟⡐⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠁⠹⡆⢇⠀⠀⠀⠀⠀⠀⠀⣄⣈⠀⠒⠀⣈⣡⣤⣾⡇⣿⢸⣿⣶⣤⣁⡀⠀⠐⠀⣀⣠⠀⠀⠀⠀⠀⠀⢀⣿⣿⠟⠈⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣀⠹⠘⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⢸⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⢸⡿⠃⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠁⠀⠀⡀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⢸⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣠⡆⢠⠀⠀⠀⠎⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⢰⣃⠀⢰⣀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⡗⠄⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⣿⡇⢸⡾⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⣿⠀⡇⣿⠀⢸⣿⣿⣿⣿⣿⣿⡿⠿⠿⠶⠿⠿⠿⢿⣿⣿⣿⣿⣿⡿⠐⠋⠀⢹⠃⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠻⠀⠀⠋⠀⠀⠹⣿⣿⣿⣿⣷⣶⠿⠿⠿⠟⢻⣿⣶⣿⣿⣿⣿⠟⠁⠀⠀⠀⠈⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣿⣷⣤⣤⣴⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⠿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⣠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⠿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⢀⠌⣼⠃⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⢀⣴⡏⢸⠿⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⡿⠃⢀⣠⣿⡟⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⡿⠟⠁⣴⣿⣿⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⡿⠋⡠⢠⣼⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣶⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣋⣡⣴⣿⢁⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⠏⠀⣰⣷⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠛⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⠇⣾⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣾⣿⣿⣿⣿⣿⠃⠀⣰⣿⡿⠀⠀⠀⠀⠀⠀⠀⢀⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠀⠀⠉⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣟⣘⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⢀⢠⢠⣶⠆⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⠇⠀⣰⣿⣿⠇⠀⠀⠀⠀⠀⠀⠰⠿⢛⡀⠀⠀⠀⠀⠀⠀⠀⠈⣰⣶⣷⣶⣶⣦⣭⣙⠿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⠟⣫⣥⡶⠀⠀⣾⣿⣿⣿⠈⢸⡿⠀⠀⠀⠀⠀⢨⣍⣙⣛⡛⠿⢿⠏⠀⢰⣿⣿⣿⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣷⣌⠻⣿⣿⣿⣿",
"⣿⣿⣿⣿⠟⣴⣿⣿⣿⠇⠀⣼⣿⣿⣿⡿⡀⡿⠁⠇⠀⠀⢸⠀⢸⣿⣿⣿⣿⣿⡆⠀⠀⣾⣿⣿⡇⠀⠀⠀⠀⠀⠀⣾⠟⠻⠿⠇⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡙⣿⣿⣿",
}
M.chopper = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠛⠛⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⡿⢛⣩⣭⣉⠻⠿⣿⣿⣿⣿⣿⣿⣿⠿⠛⣉⠉⠁⠀⠀⢀⣤⣤⠀⠀⠀⠀⠀⠀⠉⠙⠻⢿⣿⣿⣿⡟⣡⣶⣿⣿⣆⠙⡛⢿⣿⣿⣿⣿⣿⣿",
"⣿⣿⡟⣰⣿⣿⣿⡟⣸⣦⢸⣿⣿⣿⠿⠋⠀⠠⠾⣛⣀⣠⣤⣀⣬⣉⣉⡀⠀⠀⣴⣦⡀⠀⠀⠀⠀⠈⠻⠏⣼⣿⣿⣿⠟⣥⣾⣿⠎⡿⠿⣿⣿⣿⣿",
"⣿⡟⢰⣿⣿⣿⠏⣴⡿⠋⣼⡿⠋⣡⠆⢀⣤⣾⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⣿⣶⣌⡉⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⡿⢁⣾⣿⣿⢏⡜⢰⣷⡈⢻⣿⣿",
"⡟⢡⣿⣿⡿⠋⣼⡏⢂⣼⠟⠁⠀⣡⣶⣿⡿⢋⣩⣅⡀⠀⢀⣤⣶⣶⣦⡀⠈⠛⢿⣿⣦⠀⣠⣶⣦⠀⣸⣿⣿⡟⢱⣿⣿⡿⢣⣾⡇⢸⣿⡇⢢⠹⣿",
"⠇⣾⣿⡟⠁⣼⠞⠂⡾⠃⣠⠄⠰⠛⠉⡅⢄⠈⠉⣛⠛⠿⣿⣿⣿⠛⠉⠀⠀⠀⠀⠙⣿⣧⠈⠉⠁⠀⣿⣿⣿⠁⣿⣿⡿⢡⣿⣿⠇⣾⣿⡇⣼⢠⠘",
"⠀⣿⣿⠁⢰⠿⠀⣸⠇⠘⠋⡀⠀⠁⠀⠀⠀⠀⠀⠀⠈⠁⠒⠬⢉⠻⠶⡄⠀⠀⠀⠀⢸⣿⣧⠀⠀⠀⢿⣿⣿⣠⣿⣿⢃⣿⣿⣿⢸⣿⣿⠇⣿⢳⡆",
"⣇⢻⣿⠂⡀⠀⠁⠛⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⣄⠀⠀⠀⠀⣼⣿⣿⠀⢾⡇⢸⡿⣿⣿⣿⣿⠀⢿⡿⢃⣿⣿⡏⣸⡟⣸⠀",
"⣿⡌⢿⣶⣷⣈⣐⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠁⠠⠀⠺⣿⣿⡿⠀⠀⠀⠸⡿⢿⣿⣿⣿⣄⣠⣴⣿⣿⠟⣴⡟⣰⡟⢰",
"⣿⣷⣌⢻⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⣿⣿⣿⣿⣷⣦⣄⠀⠀⠀⠀⠀⠀⠂⠈⠛⢡⣾⣦⠀⠀⠩⠍⢚⣿⣿⣿⣿⣿⣿⣥⣾⠏⣴⡿⢡⣿",
"⣿⣿⣿⣧⡙⠻⠐⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⠆⠀⣴⣶⣶⡀⠀⠉⠉⠀⠀⠀⠈⢐⣄⣻⣿⣿⣿⣿⣿⣡⣾⡟⣡⣿⣿",
"⣿⣿⣿⣿⣿⣶⡈⠀⠀⠀⠀⠀⢀⣼⣿⡿⠋⣉⣉⣹⠟⠉⠙⠻⣿⣿⣿⢀⣠⣄⡈⠹⣿⣷⠀⠀⠀⣰⢂⠢⠠⠿⠿⠉⠃⢋⠛⠋⢹⠿⢋⣴⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⡦⠄⠀⢤⣤⡈⠻⠟⢀⣾⣿⣿⣿⣷⠠⣶⣿⣿⠿⣿⣿⣿⡿⠿⠄⣈⣡⣧⠀⠀⢻⡘⢿⣦⠑⠈⠀⠀⠀⠈⢠⣤⣾⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⠋⠀⠀⠀⣸⣿⣷⠘⠟⠛⢛⣿⣷⣌⠛⠁⠈⠛⢡⣾⣿⣿⣿⣥⣀⢀⡀⠉⣩⡀⠀⠀⣤⣤⣤⣀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⢉⠀⠀⠀⢠⣿⣿⣿⣇⡘⢰⣿⣿⣿⣿⡇⢠⣈⠁⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠹⣿⣿⣿⣿⡄⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⠀⠈⠗⣀⡘⠋⠋⠉⣉⣙⠒⢤⡙⠻⣿⡇⣾⣿⠂⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠈⢉⠹⠿⠃⣠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣦⡀⢰⣿⣇⣀⣽⠈⢿⡿⢿⣶⣌⡓⢶⣄⣙⠻⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠋⠀⠀⠀⢀⣠⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣄⣙⣛⣫⡄⢧⠀⠀⠫⠉⠿⠿⠶⠌⠻⢿⣷⣤⡍⠛⠻⠿⠟⠫⢙⣀⠠⠤⠄⣀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡷⠘⣧⡀⠀⣤⠶⠤⠥⠄⣥⠄⠈⠿⠆⠤⢴⣦⣤⡀⠄⡀⠀⠀⠀⣿⡀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠘⠿⢂⠀⠀⢀⠀⠬⠅⠂⡀⢀⡀⠐⢒⡂⠉⠛⢶⣌⠢⡀⠀⢻⡧⠀⠀⠘⣛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⢀⣾⡆⠀⠀⠄⣿⣇⠀⣀⣸⣿⣶⠍⠠⢀⠀⠃⠈⢦⡙⢷⣤⣀⣉⡐⠷⠀⢀⡙⣇⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣅⠀⢠⡿⠁⠀⣰⡶⠀⢀⠻⣷⣄⡙⢿⣿⠀⠶⠾⢰⣄⠀⠀⠁⣼⣿⡿⠋⠁⢀⠀⠿⠇⣸⡄⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⣠⣾⡿⠁⠈⠀⠑⣂⣙⠻⠶⣬⣑⣀⠠⠿⠟⣛⡋⠀⠙⠋⠀⠀⡀⠐⢸⣛⣩⣤⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣰⣿⣿⠃⠀⠀⠀⢰⣿⣿⣿⣶⠖⠈⠭⠍⣉⡙⠋⢹⣴⣢⠀⠈⠘⠁⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠻⣿⡟⠀⠀⠀⠀⢠⣽⣿⣿⡟⠀⠀⠀⠉⣼⣿⠗⠀⢿⣿⠀⡄⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠰⣿⣿⡄⠀⠀⠀⠈⠛⠛⠛⠀⠀⠀⠀⠀⣿⣿⠃⠰⠀⠉⠀⠔⠲⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
}
M.sanji = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢋⣴⡿⢋⣶⣿⣿⣿⠟⣡⣾⠟⣩⣴⣾⣿⣿⠟⣡⣾⣿⣿⡇⠈⠉⠙⣿⣿⠻⣦⡙⣿⣿⣦⡹⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢋⣴⠟⣩⣴⣿⡿⣩⠟⣵⡿⢋⣴⣾⣿⣿⡿⠛⢁⣾⣿⠟⣹⣿⠇⠠⢶⣧⠘⢿⣷⡘⣷⡘⣿⣿⣷⡜⢿⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⠿⠛⠉⠖⣋⢁⣼⣿⣿⠋⣼⣿⣿⡟⣡⣿⣿⣿⣿⢟⡡⢠⣿⡿⢁⣾⢹⣿⠀⢰⣦⡙⡁⠈⢿⣷⠹⣷⡸⣏⢿⣿⣎⢿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢣⣾⣿⣿⢃⣾⣿⣿⠏⣰⣿⣿⣿⡿⢃⡾⢣⣿⡟⢠⣿⡿⣸⡿⠀⣾⣿⣿⡄⠀⠈⢻⣧⢻⣧⢹⣆⢿⣿⡆⢿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢡⣿⠟⣽⠃⣾⣿⣿⡟⣸⣿⣿⣿⣿⢡⣿⢣⣾⠋⢠⣿⣿⠃⣿⠃⢰⣿⣿⣿⣿⡄⠀⢀⣿⡎⢿⣇⢻⡌⣿⣿⡘⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⣾⡟⣼⡏⣼⣿⣿⡟⣰⣿⣿⣿⣿⢁⣿⡏⣼⡿⢠⣿⣿⡿⢰⡏⠀⣾⣿⣿⣿⣿⣿⡄⠂⢹⣷⠸⣿⡌⣧⢸⣿⣇⢻⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⡏⣼⣿⢣⣿⢣⣿⣿⡟⢰⣿⣿⠇⣾⠇⣿⣿⢠⡿⢃⣿⣿⣿⠇⣿⠃⣰⣿⣿⣿⣿⣿⣿⣿⡌⠈⣿⡆⣿⣧⢻⡎⣿⣿⣆⢿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⢰⣿⡏⢸⣿⢸⣿⡟⠀⣾⣿⡏⣸⡟⣸⣿⡟⣸⠇⣼⣿⣿⡟⢸⠏⢠⣿⣿⠿⠿⣿⣿⣿⣿⣷⠀⢹⡇⢹⣿⠘⡇⢻⣿⣿⠘⢿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⡇⣾⣿⡇⣿⣿⢸⣿⠁⢠⣿⣿⢰⣿⢡⣿⣿⡇⡿⢸⣿⣿⣿⢁⡟⠀⡼⢋⣴⣿⣧⡙⣿⣿⣿⣿⣇⠈⡇⡸⣿⡆⣧⠈⣿⣿⠀⣆⢿⡇⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⠀⣿⣿⢸⣿⣿⢸⡟⠄⣼⣿⡏⣼⡇⣾⣿⣿⡇⠀⣿⣿⣿⠏⣾⠓⣰⡇⣿⡥⠶⠞⣠⣿⣿⣿⡿⢛⠀⡟⡄⣿⡇⣿⠀⣿⣿⢰⣿⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⠐⣿⣿⢸⣿⣿⢸⡅⢰⣿⣿⡇⣿⢇⣿⣿⣿⠃⠀⣿⣿⡏⣰⠁⢠⣿⣧⡙⢷⣶⣾⡿⠟⠋⣡⣶⣿⡆⠃⣧⣸⡇⠋⠀⢻⣿⢸⡿⢸⡗⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⡇⢿⣿⡘⣿⡟⡈⠁⡏⣿⡿⢸⣿⢸⣿⣿⢻⡄⢸⣿⡟⣰⡟⢁⣾⣿⣿⠿⠂⠀⡀⢀⣠⣬⣭⣙⠻⡇⢀⢸⣿⠇⢀⣽⢸⣿⢸⡇⣾⠇⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⡜⢿⡇⢻⠁⠠⢸⠀⣿⡇⢸⡇⢸⣿⡏⣿⡇⣼⡟⢠⡏⠀⢾⣿⣿⣁⣀⣀⣠⣴⠿⠟⠛⠛⠿⣷⠀⣄⢸⢿⢠⣤⡏⢻⡇⢸⠁⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣷⡜⡇⠀⣤⠀⣾⠀⣿⡿⢸⣇⢸⣿⠃⣿⣇⠹⠁⢸⠃⢠⠈⣿⣿⣿⣿⣿⣯⣀⣀⣤⣶⣦⣤⡀⠸⠟⠘⡇⠀⣾⣿⠈⢷⠈⠸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠁⢰⣿⣁⢿⡆⢿⣧⢸⡄⢸⣿⠀⢻⣿⠀⠀⠨⠀⡿⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠘⢠⠀⣿⣿⢠⡈⠀⠰⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢀⡌⣿⣿⡈⡇⢸⣿⣼⡇⢸⠟⠀⢸⡏⠀⠀⠀⢸⣗⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⢸⠀⠹⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣥⣿⣇⢹⣿⣿⣷⠀⣿⣿⠃⠈⠀⠀⡸⠁⠀⡀⢀⠹⠇⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣾⠀⠈⠀⢀⡌⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠈⢡⠸⣿⡆⠸⠋⢀⡄⠀⠀⠁⣠⣾⣧⣸⣷⣄⡉⢟⣭⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠄⠀⠸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⣰⣿⠀⠟⠀⠀⡀⢸⣿⣦⣴⣾⣿⣿⣿⣿⣿⣿⣽⣦⣉⣣⣵⣤⣖⣴⠶⠟⢛⣿⣿⣿⣿⠃⢀⠐⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣀⣴⣧⠀⠹⣿⣿⣿⣯⣭⡝⠛⠛⣛⣋⣭⣭⣭⣭⣭⣭⣭⣥⣶⣶⣾⣿⣿⣿⡿⠃⣰⡏⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⣀⠀⠙⢿⡿⢋⠥⢊⣥⣾⣿⠿⠿⣿⡿⠿⠿⠿⣿⣿⣿⣿⣿⣿⣿⡟⠁⡀⠹⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⢠⠖⣡⣶⣿⣿⣿⣿⣷⣶⡤⠠⣤⣶⣾⣿⣿⣿⣿⣿⡿⠋⡀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⣠⣶⣌⠻⢿⣿⣿⣿⠟⠿⠃⠀⣿⠟⢻⣿⣿⣿⡿⠋⢠⣾⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠟⠛⠃⢸⣿⣿⣷⣄⠙⠉⠛⠀⠈⠀⠀⠉⠀⠈⠋⠀⠋⣠⣴⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⠁⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣦⣤⣀⣀⣀⣀⣀⣀⣤⣤⣤⣾⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⢰⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⡁⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢀⣾⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⠀⠀⠀⠀⣼⣷⣄⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⡡⢹⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠠⣾⣿⣿⣿⣷⣄⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣡⣾⠁⣾⣿⡿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ",
"⣿⣿⣿⣿⣿⣿⣿⠟⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠿⣿⣿⣿⣷⣌⡙⠿⣿⣿⣿⣿⣿⣿⠟⣡⣾⣿⡏⡸⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⣿⣿⣿⠿⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣶⣌⣙⠛⢛⣉⣠⣾⣿⣿⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
}
M.brook = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠒⠀⠺⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠉⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠁⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⠋⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⠋⠻⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⡿⢿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡻⣿⣿⣿⣿⣿⣿",
"⣿⣿⡿⠛⢻⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠚⢿⣿⣿⣿⣿",
"⣿⡟⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿",
"⣿⠷⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⣤⣴⣦⣷⣷⣷⣶⣶⣠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠨⠛⣿⣿⣿",
"⠟⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠻⣿⣿",
"⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⢿⣿⣿⡿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠋⢹",
"⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣷⣭⣵⣾⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⣾",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⣾⣿⣿⣿⣿⣿⣿⣷⣜⢿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⣫⠵⠛⠉⠉⠛⣿⣿⣷⡿⡻⠿⠿⠿⢶⣝⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣹⣿",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠃⠀⠀⠀⠀⠀⢸⣿⣯⡞⠀⠀⠀⠀⠀⠹⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⣹",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣇⠀⠀⠀⠀⠀⢠⡿⣿⣿⡁⠀⠀⠀⠀⠀⢀⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢈⣿",
"⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠖⠦⠤⢶⣶⢏⣴⠏⠻⣷⣤⣤⠤⠀⠠⠞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣻",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠛⠟⢿⣿⣿⣿⣏⢀⠀⢸⣿⣿⣿⣿⠿⡳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢦⣿",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠚⣡⡝⣫⡝⣫⢝⣝⢟⡟⠛⠅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿",
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠿⠇⣿⡇⣿⢸⣿⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣿",
"⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠄⣄⠀⠈⠀⠉⠀⠈⠁⡀⢤⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿",
"⣶⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣰⢶⣾⣟⢵⡇⣿⠀⠀⠀⠀⠀⠀⢰⡇⣑⢕⡵⣯⣶⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣦⣴⣿⣿",
"⣿⣇⢀⠀⠀⠀⠀⠀⣀⣴⣾⣿⣿⣷⣗⣝⣽⣻⣥⣿⠀⠀⠀⠀⠀⠀⢸⢷⣕⢍⢔⣾⣿⣿⣿⣿⣶⣤⣄⡀⠀⠀⠀⠀⢠⣼⣿⣿⣿⣿",
"⣿⣿⣇⡀⠀⢀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⣿⠀⠀⠀⠀⠀⠀⢸⢸⣵⣷⣿⣾⣿⣿⣿⣿⣿⣿⣿⠿⠓⠀⠀⠀⣴⣿⣿⣿⣿⣿",
"⣿⣿⣿⣇⣀⠀⠈⠙⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡟⠀⠀⠀⠀⠀⠀⢸⢸⣿⣿⣿⣿⣿⣿⣿⣿⠿⠋⠁⠀⣠⣠⣤⣶⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⠀⣴⠀⠀⠀⠉⠻⣿⣿⣿⣿⣿⡟⣸⠃⠀⠀⠀⠀⠀⠀⠸⡾⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⣤⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣶⡀⠀⠀⠀⠈⠙⢿⣿⣿⢣⣿⠀⣿⣼⣶⣶⢰⣶⠀⣇⢿⣿⣿⣿⠟⠁⠀⠀⢠⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡶⠄⠀⠀⡠⣻⡯⢑⡙⢶⣤⣍⣤⣋⣬⣤⢔⣑⢿⣿⡟⠁⠀⠀⠠⠾⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⡿⠟⠛⠉⠀⠀⣠⣴⣿⣿⣿⢻⡜⠿⣦⡙⢷⣦⣶⠖⡱⠟⣋⢼⣿⣿⣶⣄⡀⠀⠀⠀⠀⠉⠛⠻⠿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠈⠙⢿⣿⡇⠿⠿⣥⡌⠉⠀⠈⠀⠀⠀⣪⢱⣾⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⣿⣿⣿⣿",
"⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣦⡷⣂⣤⢠⣦⣶⢰⣦⠙⢿⣿⣿⣿⡿⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿",
"⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⢋⣾⣿⣷⣿⢿⣿⡏⣿⣷⢪⡻⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿",
"⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⢟⣼⣟⣿⢸⡟⣿⢹⣿⢡⢻⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿",
"⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⢫⣿⡟⣾⡏⢿⣿⣿⢸⣿⡏⣧⢳⡕⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿",
"⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⡿⣳⣿⡟⣼⣿⣧⣿⣿⣿⢸⣿⣧⣿⣿⣿⣎⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠠⠛⠛⣱⣿⡟⣼⣿⣿⣸⣿⣿⣿⢸⣿⣿⢿⣿⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⡿⠹⠋⠈⠡⢹⣿⣿⡿⣸⣿⣿⠸⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠋⠁⠁⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿",
}
M.jango = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠈⣿⣿⣶⣌⠻⡶⣬⡙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣰⣿⣿⣿⣿⣷⠀⢈⠻⣦⡙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢁⣼⣿⣿⣿⣿⣿⠃⣶⡀⠑⢜⢷⠘⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⣫⣿⣿⣶⣿⣷⣶⣬⣍⡛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣡⣾⡿⢛⣵⣿⣿⡟⠁⣼⣿⣿⡀⠈⠂⠃⣿⣿⣿⣿⣿⣿⠟⢃⡴⢋⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣍⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⢡⠾⠋⣁⣴⣿⣿⠟⣋⠀⢾⣿⣿⣿⣿⣄⠠⠀⣿⣿⣿⣿⣿⢋⣴⡿⣱⢿⣿⡿⠟⣛⣩⣭⣭⣍⣛⡛⠿⣿⢷⡈⢿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⣡⣴⣾⡿⠿⠟⢀⢇⠟⣻⢆⠙⠿⠿⣿⣿⣧⠀⣿⣿⣿⡿⢁⣾⡟⣰⠙⣮⢋⣴⣿⣿⣿⣿⣿⣿⣿⣿⡦⢡⣾⣿⡄⢻⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⣰⣿⠿⠋⠁⠀⠀⢸⣎⣂⣀⠋⣼⡆⠀⠀⠀⠉⠛⢇⠹⣿⣿⢁⣾⡿⣰⣷⣠⣾⣌⢿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⡇⠘⣿⡈⢿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⠿⠛⣋⣭⣭⣬⣍⡛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢡⠟⠁⠀⠀⠀⠀⠀⠈⠻⣿⡷⠢⠟⠁⠀⠀⠀⠀⠀⠀⠀⠹⠇⣾⣿⢡⡟⢨⠟⣍⢻⡌⢿⣿⣿⣿⣿⣿⣿⣿⡇⣾⢀⣷⡙⠇⣸⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⠟⣉⡴⠞⡛⣛⡛⠛⠛⢻⣉⣑⣮⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⢸⣮⣒⡒⠀⣴⠠⠴⠒⠒⠂⠀⠀⠀⠀⠐⣿⡏⣼⣿⡞⠀⠘⠣⠹⡌⢿⣿⣿⣿⣿⣿⣿⠇⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿",
"⣿⣿⡥⢚⣥⣶⡟⣰⡿⠀⠌⢀⣶⣌⠻⣿⣿⣶⣍⡻⢿⣿⣿⣿⣿⣿⡿⠟⡋⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠉⡛⢓⡡⠔⢀⣀⠄⠀⠄⠸⢿⣿⣇⢢⡜⠣⣭⣶⣶⣿⣿⣿⣷⣶⣦⣬⣉⡛⠻⢿⡿⠀⢰⣿⣿⣿⣿⠿⠟⣛⣿⡿⢻⣿",
"⣟⡥⠾⢿⣿⡟⣰⡿⠁⡐⠀⣼⣿⣿⣷⣌⢻⣿⣿⣿⣶⣍⡛⠛⣛⣥⣶⡟⠀⠀⡔⠡⣾⣿⣿⠆⠀⢈⠘⢿⣦⡍⢠⡅⢏⠀⢴⣿⣿⡆⠀⠨⢻⡄⣿⡀⢿⣿⣿⣿⣿⡿⣿⣿⣿⣿⣿⣿⣧⡰⣦⣤⣉⣉⣩⣥⣶⣶⣿⡿⢋⣵⣿⣯",
"⣿⣿⣿⣶⣶⣄⢻⠁⠰⠁⢰⣿⣿⣿⣿⣿⣧⡙⣿⡿⢛⣡⣴⣾⣿⣿⡿⠀⠀⠘⣧⡀⠀⠀⠀⠀⢀⠼⠘⣦⣈⡁⣨⡄⠈⠀⠀⠉⠉⠀⢀⡠⠸⣷⣿⣧⢸⣿⣿⣿⣿⣿⡎⠻⣿⣿⣿⣿⣏⢇⢈⢿⣿⣿⣿⣿⠿⢛⣩⣾⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣦⠠⠃⢠⣿⣿⣿⣿⣿⣿⡿⠓⠀⢾⣿⣿⣿⣿⣿⣿⠇⠀⠀⡐⠟⠀⢻⣶⠂⢹⣇⠀⡄⣝⣻⣂⠀⡀⡄⠀⣸⡟⠙⣿⠁⠑⢨⡉⢩⢻⡈⣿⣿⣿⣿⣿⣿⣦⠸⠛⣛⣛⣛⣂⡁⢐⣛⣋⣭⣐⢿⣿⣿⣿⣿⣿⢿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣦⠘⣾⣿⣿⣿⣿⠟⠋⠀⣠⣶⣎⠻⣿⣿⣿⣿⡿⠀⣠⠞⠁⠀⣐⡚⠛⠀⠈⣡⣼⡇⢬⣥⣖⢩⢧⣿⣦⣄⡁⠀⣈⣠⣴⣿⣿⢸⠀⡁⣿⣿⣿⡿⠟⢉⠄⢸⣿⣿⣿⣿⣿⡇⠀⠙⣿⣿⣿⣷⣬⡛⢿⣿⠇⣾⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣧⠘⣿⡿⠋⠁⢀⣴⣾⣿⣿⣿⠃⠀⢩⣝⣛⠃⡴⠃⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⠀⣦⣭⣍⢰⠂⢻⣿⣿⣿⣿⣿⣿⣿⣿⣏⣈⡀⡇⢻⠟⢉⣤⣾⠉⠀⣸⣿⣿⣿⣿⣿⠀⠀⠀⢹⣿⣿⣿⣿⣿⣶⠆⣼⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⢹⠄⣨⣴⣿⣿⣿⣿⡿⠃⡀⢀⣿⣿⣿⠘⠁⢀⣾⣿⠿⠿⢿⣿⣿⣿⠿⢛⣳⣮⢉⡁⣴⡚⠘⠻⠿⣿⣿⠟⠉⠉⠻⣿⣿⢰⠋⢀⣴⣿⣿⠏⡀⠀⣿⣿⣿⣿⣿⣿⠀⠀⢸⢸⣿⣿⣿⣿⣿⠏⣼⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡂⢺⣿⣿⣿⣿⣿⡿⠁⡐⠀⠎⣿⣿⡇⠀⢠⣿⡿⠁⠀⠀⠀⡿⠋⢠⣶⣿⠏⠀⠙⠃⠀⢩⡃⣷⣄⠈⠙⣠⣦⠀⠀⠸⣿⣮⠄⠈⣿⣿⡏⠀⠀⢀⣿⣿⣿⣿⣿⣿⠀⠀⠈⢸⣿⣿⣿⣿⠋⣼⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡘⣿⣿⣿⣿⡿⠃⡰⠁⡼⢰⣿⣿⠁⢠⣿⣿⠁⠀⠀⠛⠊⠀⣰⣿⣿⠏⠀⠀⠀⠀⠀⠀⢿⣿⣿⣦⡀⠀⠉⠀⠀⢠⣿⠃⠀⠀⣿⣿⠇⠐⠀⢸⣿⣿⣯⣿⣿⡿⠀⠀⠀⠘⣿⣿⣿⢃⣾⣿⢟⡻⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠹⣿⣿⣿⠁⢰⠃⢰⠃⣿⣿⣿⠀⢸⣿⢻⣧⣀⡀⣀⣀⣼⣿⣟⣡⣄⠀⠀⠀⠀⠀⢀⣀⣙⣿⣿⣿⣦⣤⣤⣴⠟⠁⠀⡘⠀⡷⣿⠀⡄⠀⢸⣿⣿⣿⣿⣿⡇⠀⢸⠀⣶⣿⠟⢡⣾⣿⡏⢸⡆⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠹⣿⠇⢠⡏⢀⡏⣸⣿⣿⣿⢰⡇⣿⢖⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡦⠀⠀⠀⢴⣿⣿⣿⣿⣿⣿⣿⣿⠿⠃⠀⢀⡸⠁⠀⣿⡏⢀⠀⠀⣾⣿⣿⣿⣿⣿⡇⠀⠘⠀⢉⣡⣴⣿⣿⣿⠇⣸⡇⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣅⠉⠄⡾⠀⣼⢡⣿⣿⣿⡿⢸⣷⠡⠁⢜⣿⣿⣿⣿⣿⣿⣿⣿⣏⣀⣀⡠⠄⣠⣽⣿⣿⣿⣿⣿⠟⠁⠀⠀⣠⡾⠀⠀⠀⣿⠇⠘⡀⠀⣿⡿⠿⢛⣋⣡⣴⣶⣾⣿⣿⠀⠀⠻⣿⣿⠀⣿⠇⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠘⢧⣰⡇⣼⣿⣿⣿⡇⣸⣿⠀⢪⠢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⠀⠀⠀⣠⣾⠏⠀⠀⠀⠀⣿⠀⡄⠀⠂⠁⠀⠀⠀⠀⠈⠿⣿⣿⣿⣿⠀⠩⢦⠙⠏⠈⣿⢀⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡗⠈⠻⣿⣿⣿⣿⣿⡇⣿⡥⠂⠁⡜⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⠉⠀⠀⠀⢀⣠⣾⠟⠁⠀⠀⠀⠀⠀⣇⡤⠃⠀⠀⠀⠀⠀⠀⠀⠀⢈⢸⣿⣿⡇⠀⡀⢣⠱⣄⣤⡇⣸⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠉⠁⠀⠀⠈⠙⠿⣿⣿⡇⣿⣧⡀⣴⡄⠾⢛⣛⣫⣭⣭⠙⣿⣷⣶⣶⣶⣶⣶⣶⣶⣶⣦⣤⣭⣋⣁⠀⠀⠀⠀⠀⠀⠀⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠃⠘⢿⣿⢀⢡⣿⠈⣷⣿⣿⢡⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⠉⠀⠀⠀⠀⠀⠀⠀⠈⠻⡇⣿⡿⠋⠁⠲⠿⠛⢛⠩⠍⣁⡤⠤⠖⠒⠒⠒⠒⣀⣀⣐⣒⣈⠉⠭⣭⡙⠛⠁⣠⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠃⠄⣾⠟⣰⣿⣿⠃⣾⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡟⠁⠻⠂⠀⡀⠦⠴⠞⣩⣥⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣬⣀⠄⠈⠀⠤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣣⣾⣿⣿⠏⣼⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣦⡄⠀⠀⠀⠀⠀⠀⠀⠐⠿⠁⢠⣄⢌⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠋⢈⡆⠀⠐⠖⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⢀⣿⣿⣿⠋⣼⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡹⣧⣕⠦⣍⣛⠿⠿⠿⠿⠿⠿⠿⠛⠯⠭⠿⣟⣛⡩⠅⠢⢂⣴⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⣫⣴⣿⣿⡟⣁⣾⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⢋⣢⣴⣤⣤⠀⠀⠀⠀⠀⠀⠀⠈⢮⡛⢿⣶⣬⣭⣛⣛⣛⡻⠿⠿⠿⠿⠛⠛⠋⠭⠴⠾⠆⡪⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⠟⢁⣴⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢟⣫⣥⣬⡲⠦⢝⢿⣿⣿⣤⣤⠀⠀⠀⠀⠀⠀⠀⠉⠓⠎⠉⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠂⠀⠔⠚⢛⣛⣥⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
}
M.jimbei = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠁⠀⠀⠀⠹⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢉⡄⢀⢀⠀⠆⠀⠀⠀⠀⢘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠉⠃⠐⢶⣥⣤⣤⣴⠚⠅⢀⠀⡐⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠠⢰⠀⡐⠻⠿⡎⢉⠄⡲⠿⠐⣘⢇⠘⣿⣿⣿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠠⢀⢾⣷⣄⠘⠛⣈⣰⡶⣠⢹⣶⣆⢠⠀⠀⠉⠉⠁⠐⠄⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠉⠀⠬⢌⣼⠐⡝⢟⣫⣭⣭⣟⣑⠣⢿⣿⣿⣆⢆⢃⠄⡀⠀⠀⠀⠀⠈⠻⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠋⠉⠀⠀⢁⣴⣾⡟⣨⣾⣿⣷⠾⣶⣿⣿⣿⣶⣍⣻⣍⢳⣶⣿⠿⠓⣀⣄⠀⠀⠀⠀⠈⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⢉⣤⠲⠄⢀⡀⢶⣌⠻⣿⣿⣿⣿⡏⠁⠀⠀⠉⢻⣿⣿⣿⣿⣿⡜⢛⣥⡶⠟⣩⣤⡶⠶⢀⡀⠀⠀⠙⣉⣬⡙⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⢠⠟⣀⢆⠀⠀⠻⣦⣝⢻⣿⣿⣿⣿⣀⠀⠀⣀⠀⣴⣿⣿⣿⣿⣿⣿⣮⢫⣶⣿⢛⠡⠐⠊⠁⢀⡤⢖⣫⣭⣶⣮⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢁⠊⢌⣉⣑⡕⢄⠐⢾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠛⠉⠀⠀⣀⠴⠚⢁⣊⡭⠽⣒⣒⣶⣖⣀⡈⠻⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⠋⡡⢐⣭⣶⣿⣿⣿⡿⠃⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠁⠀⠀⢀⢔⣪⣥⣶⣟⣋⣁⠶⢿⣿⣿⣿⣿⣿⣿⠀⢿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⠿⠛⠂⠰⠿⢿⣛⣛⣫⠭⡒⠈⣂⡠⡀⠀⠀⠙⢿⡿⣩⡆⣾⣿⡇⡎⡿⠿⠿⠛⠁⠀⠀⠀⠀⠀⡣⢉⠭⣍⣉⡉⠹⢿⣿⣕⠢⢍⣛⠿⢿⣿⠀⢾⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⠁⠖⣚⡭⠭⠭⣉⠉⠥⣶⣿⡇⠀⠈⠻⣮⡂⠀⠀⠀⠑⠽⣓⡪⠭⢞⡓⠚⠁⠀⠀⠀⢀⣀⣢⣴⡾⠊⠀⠙⠪⡙⢿⣿⣶⣬⣙⢷⠰⣮⣭⣥⣢⣥⡈⠻⣿⣿⣿⣿",
"⣿⣿⣿⣿⡿⠀⡙⠏⠐⢉⣡⠤⢒⣢⣤⣭⣤⣤⣤⣤⣬⣭⣤⣤⣶⠄⢤⣤⣬⣿⡄⠤⣤⣀⠀⡠⣂⣽⡿⠋⠁⢀⣠⡶⣋⣵⣜⢶⣌⢙⠻⢿⣿⣷⡘⢿⣿⣿⣿⣿⣆⠘⣿⣿⣿",
"⣿⣿⣿⠋⠀⢀⡶⢐⠀⢜⣥⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⡌⡙⠿⠿⢋⣴⣌⠻⣳⣬⡍⡁⠀⠠⣒⣛⠩⣾⣿⣿⣿⡄⢻⣷⣌⠲⣭⡛⢄⢻⣿⣿⣿⣿⣿⣆⠸⣿⣿",
"⣿⡟⠁⢀⣾⡋⣼⢡⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢱⠁⠸⠿⠿⢿⠱⠲⣶⣶⣶⣶⣿⣿⣿⣿⣿⣷⣔⢌⠙⠟⣡⣧⠛⣿⣷⡈⢿⣶⣼⣿⣿⣿⣿⣿⣿⡆⢹⣿",
"⡏⠀⣰⣿⣿⢸⡇⠸⠿⠋⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⡌⢟⣛⣱⣿⣤⢠⢻⣿⣿⣿⣧⢻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠻⣮⣿⣿⣧⠘⣿⣿⡰⡙⢿⣿⣿⣿⣿⣿⣿⣿⠀⣿",
"⡇⢇⢿⣿⣿⡘⢛⡄⣿⣿⡆⠃⢹⣻⣿⣿⣿⣿⣿⡿⣸⣿⣿⣿⣿⣿⢻⢸⣜⣿⣿⣿⣛⢸⡜⣿⣿⣿⣿⣿⣿⣿⣿⣿⢈⣣⡹⣿⣿⣿⠎⡨⣴⣶⣿⣎⠻⣿⣿⣿⣿⣿⣿⡆⣸",
"⣷⣄⣈⡻⢿⣷⣌⢿⠈⣿⡷⣹⣿⣻⣿⠿⣿⣿⣿⣶⣿⣿⣿⣿⣿⡟⡌⠻⠿⢿⣿⣿⣿⢸⡇⣿⣿⣿⣿⣿⣿⣿⡿⣣⣾⣿⣷⣾⣿⠊⣾⠀⣿⣿⣿⣿⣷⣹⣿⣿⣿⣿⣿⣷⢸",
"⣿⣿⣿⣷⣶⣬⠙⠷⣌⢹⢇⣿⣿⣿⣿⣿⣶⣮⢹⣿⣿⣿⣿⣿⡿⢁⠀⣾⣶⣦⠀⢨⡭⣸⡇⠸⡛⢿⣿⣿⣛⣥⣾⣿⣿⣿⢏⡼⣡⣷⣌⣀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢸",
"⣿⣿⣿⣿⣿⣿⣿⡶⠘⢼⣎⡻⢿⣿⣿⣿⡿⢣⣾⣿⣿⣿⣿⡿⢁⠂⣰⣿⣿⣿⡇⡘⡇⡿⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⢟⡵⢋⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢸",
"⣿⣿⣿⣿⣿⣿⣿⣷⡄⠜⢿⣿⣷⣶⣭⣥⣾⣿⣿⣿⣿⣿⠟⡵⢁⣼⣿⣿⣿⣿⡇⠡⠸⣱⣿⣿⣿⣿⣿⣿⣿⡿⠋⠱⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠿⠿⣿⠿⢁⣼",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣄⣀⢋⡙⠿⠿⠿⠿⠿⠿⠿⠟⢁⣴⣿⣿⣿⣿⣿⣿⣇⠠⠛⣛⣛⣛⣛⣛⢛⣋⣁⣴⣾⣷⣦⣉⣙⣛⣛⣛⡛⣛⣛⣛⣛⣋⣠⣶⣿⣷⣶⣶⣶⣿⣿",
}
M.kinemon = {
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⣴⠆⣶⣎⢻⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠋⠭⣴⣶⣾⣿⣿⢈⢹⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢛⣭⣴⣶⣿⣿⣿⣿⣿⣿⣿⣧⠘⣀⣭⣥⢤⠢⡙",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣡⣾⣿⠋⣀⠉⠀⠉⠨⠛⠿⠿⢋⣴⣿⣿⢆⡈⢁⣳⠱",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢋⣾⡟⠻⣿⡇⣾⣷⣦⣀⣤⡖⢂⠄⠙⢿⣿⡇⠿⣿⢐⠂⠠",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢡⣿⣯⡙⠲⠬⠇⣿⣿⣿⣿⢋⣴⣿⠀⠑⢾⣿⡇⠀⣥⠐⣩⣴",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢃⣿⣷⣌⠑⢀⣴⣿⣿⣿⡟⣡⣿⣿⣿⣷⣄⢢⣽⣿⠀⣭⣾⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⣾⣿⣿⡏⡠⡭⠭⡭⠭⠉⡐⣿⣿⡟⣚⣛⣛⣂⢹⡿⢸⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣼⣿⣿⣿⠀⢄⠀⠀⠈⡐⠰⢧⢹⣿⢀⠙⠌⢻⣿⣿⢇⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢰⣿⣿⢻⠡⠁⠀⣡⣶⣿⡇⠀⠺⡆⠇⢀⢡⣤⣤⣿⠏⣼⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣱⣿⣿⡿⢃⠀⡀⠀⠸⣿⣿⡇⢐⢠⣿⣼⣿⣿⣿⡿⢋⣾⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢏⣼⣿⣿⠟⣴⠃⠁⠁⣀⠀⣿⣿⡇⣤⡙⢿⣿⣿⣿⠟⣱⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠿⣡⣾⣿⡿⠃⣊⠕⠀⠂⠀⠃⢸⣿⣿⢇⣿⣿⣿⣿⠟⣡⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢁⠀⠀⠤⠙⠻⠛⠁⠈⠁⢭⣄⠠⠀⡀⠢⣿⢃⣾⣿⣿⡟⣡⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠑⠀⠀⠀⡄⠀⢀⣼⠶⢤⠈⠀⣺⣿⡷⢡⣾⣿⣿⢋⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠘⠀⠀⠈⡀⡚⠰⠨⢰⣿⠛⣡⣿⣿⡿⢣⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⢥⣀⠨⢄⠘⠃⠀⠈⢟⡻⢡⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⠀⠀⠀⠀⠜⣰⠀⣿⣎⡋⠙⠉⠀⠠⠘⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠈⠀⠀⠀⣠⣾⣌⢳⣘⠻⡇⠀⠀⠃⠀⠀⡀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠐⠀⠀⠀⠀⠀⠀⣴⣾⣿⣿⣿⣦⣍⣥⣶⠀⠀⠀⠀⠀⢋⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠁⠀⠀⠀⠀⠀⣀⡐⢶⠸⣿⣿⣿⣿⡿⢡⣿⣿⣿⡄⠀⠐⠀⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⠰⠀⠀⠀⠀⠀⢸⢿⣿⡶⢒⣀⣒⡢⠭⠑⠻⢿⣿⣿⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠁⠠⠀⠀⠀⠀⢸⠈⢻⠀⠻⣿⣿⣿⢡⣷⣶⡄⢍⡁⠠⠤⠄⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⢁⡄⠀⠀⢸⡷⡨⠑⣴⣶⣦⠄⣈⠻⠿⢛⡼⠋⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⣼⣿⡀⠀⠘⢸⣿⣤⣛⣛⠋⠘⢿⣷⠊⠋⠀⠀⠀⠀⠐⢀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⢠⣿⣿⣿⠆⢀⣸⡙⠿⢿⡟⣰⣿⡖⡷⠁⠀⠀⠀⠀⠀⠈⠈⢈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣾⣿⣿⡏⣼⣿⣿⣷⣿⣾⠁⣦⣍⣶⢁⣀⣤⣶⠃⠀⠀⢀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⢾⣿⣿⣿⣿⣿⣿⣾⣿⣿⡇⣾⣿⣿⣿⠀⣠⣀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢁⡀⠀⠈⠙⠛⠛⠿⠿⠿⠿⠿⠇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣋⣴⣿⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣝⣛⣛⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢛⣥⣾⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⣠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣭⣍⣛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢋⣴⣿⣿⣿⣿⣿⣿⣿⣿⡿⢀⣠⣤⣤⣀⠬⢙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣍⡛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⣿⣿⠟⣵⣿⣿⣿⣿⣿⣿⣿⡿⠟⣩⣴⣿⣿⣿⣿⣿⣿⣶⣦⣭⣭⣭⣛⣛⣛⣛⠻⠿⢿⣿⣿⢻⣿⡏⢹⣿⡆⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⣿⣿⡟⣡⣾⣿⣿⣿⣿⣿⡿⠟⣩⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⠖⢠⠾⢿⣁⠜⢉⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
"⣿⣿⣿⣿⠿⢋⣾⣿⣿⣿⣿⣿⠟⣫⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢋⠔⠾⠎⣀⠇⣠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
}
M.doom = {
[[================= =============== =============== ======== ========]],
[[\\ . . . . . . .\\ //. . . . . . .\\ //. . . . . . .\\ \\. . .\\// . . //]],
[[||. . ._____. . .|| ||. . ._____. . .|| ||. . ._____. . .|| || . . .\/ . . .||]],
[[|| . .|| ||. . || || . .|| ||. . || || . .|| ||. . || ||. . . . . . . ||]],
[[||. . || || . .|| ||. . || || . .|| ||. . || || . .|| || . | . . . . .||]],
[[|| . .|| ||. _-|| ||-_ .|| ||. . || || . .|| ||. _-|| ||-_.|\ . . . . ||]],
[[||. . || ||-' || || `-|| || . .|| ||. . || ||-' || || `|\_ . .|. .||]],
[[|| . _|| || || || || ||_ . || || . _|| || || || |\ `-_/| . ||]],
[[||_-' || .|/ || || \|. || `-_|| ||_-' || .|/ || || | \ / |-_.||]],
[[|| ||_-' || || `-_|| || || ||_-' || || | \ / | `||]],
[[|| `' || || `' || || `' || || | \ / | ||]],
[[|| .===' `===. .==='.`===. .===' /==. | \/ | ||]],
[[|| .==' \_|-_ `===. .===' _|_ `===. .===' _-|/ `== \/ | ||]],
[[|| .==' _-' `-_ `=' _-' `-_ `=' _-' `-_ /| \/ | ||]],
[[|| .==' _-' '-__\._-' '-_./__-' `' |. /| | ||]],
[[||.==' _-' `' | /==.||]],
[[==' _-' N E O V I M \/ `==]],
[[\ _-' `-_ /]],
[[ `'' ``' ]],
}
M.pacman = {
[[ ██████ ]],
[[ ████▒▒▒▒▒▒████ ]],
[[ ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ]],
[[ ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ]],
[[ ██▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ]],
[[ ██▒▒▒▒▒▒ ▒▒▓▓▒▒▒▒▒▒ ▓▓▓▓ ]],
[[ ██▒▒▒▒▒▒ ▒▒▓▓▒▒▒▒▒▒ ▒▒▓▓ ]],
[[ ██▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ██ ]],
[[ ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ]],
[[ ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ]],
[[ ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ]],
[[ ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ]],
[[ ██▒▒██▒▒▒▒▒▒██▒▒▒▒▒▒▒▒██▒▒▒▒██ ]],
[[ ████ ██▒▒██ ██▒▒▒▒██ ██▒▒██ ]],
[[ ██ ██ ████ ████ ]],
}
local keys = vim.tbl_keys(M)
local function get_days()
local seconds = vim.uv.clock_gettime("realtime").sec
local day = math.ceil(seconds / (60 * 60 * 24))
return day
end
M.get_by_day = function()
local index = (get_days() % #keys) + 1
return M[keys[index]]
end
return M

225
nvim/lua/funcs.lua Normal file
View file

@ -0,0 +1,225 @@
local autocmd = vim.api.nvim_create_autocmd
local groupid = vim.api.nvim_create_augroup
local M = {}
M.get_size = function(path)
local ok, stats = pcall(function()
return vim.loop.fs_stat(path)
end)
if not (ok and stats) then
return
end
return math.floor(0.5 + (stats.size / (1024 * 1024)))
end
M.is_text = function(path)
-- Determine if file is text. This is not 100% proof, but good enough.
-- Source: https://github.com/sharkdp/content_inspector
local ok, fd = pcall(function()
return vim.loop.fs_open(path, "r", 1)
end)
if not (ok and fd) then
return false
end
---@diagnostic disable-next-line: redefined-local
local ok, bytes = pcall(function()
return vim.loop.fs_read(fd, 1024)
end)
if not (ok and bytes) then
return false
end
local is_text = bytes:find("\0") == nil
vim.loop.fs_close(fd)
return is_text
end
-- copy from https://github.com/Bekaboo/nvim/blob/master/lua/core/autocmds.lua
---@param group string
---@vararg { [1]: string|string[], [2]: vim.api.keyset.create_autocmd }
---@return nil
M.augroup = function(group, ...)
local id = groupid(group, { clear = true })
for _, a in ipairs({ ... }) do
a[2].group = id
autocmd(unpack(a))
end
end
M.pcall_notify = function(func)
local ok, out = pcall(func)
if not ok then
vim.notify_once(string.format("%s", out), vim.log.levels.DEBUG)
end
return out
end
M.is_not_mini = function()
return vim.env.NVIM_MINI == nil
end
M.doau = function(pattern, data)
vim.api.nvim_exec_autocmds("User", {
pattern = pattern,
data = data,
})
end
function M.maxline(path, break_after)
if break_after == nil then
break_after = vim.o.synmaxcol + 1
end
local max = 0
local fd = vim.uv.fs_open(path, "r", 1)
if not fd then
return max
end
local stat = vim.uv.fs_fstat(fd)
local data = vim.uv.fs_read(fd, stat.size, nil)
vim.uv.fs_close(fd)
if not data then
return max
end
local lines = vim.split(data, "[\r]?\n")
for _, line in pairs(lines) do
if max < #line then
max = #line
end
if max >= break_after then
return max
end
end
return max
end
-- Returns the first element in the array that satisfies the provided testing function
M.ifind = function(tbl, func)
for index, item in ipairs(tbl) do
if func(item, index) then
return item
end
end
return nil
end
-- Function to merge two tables in Lua using Neovim.
function M.merge_tables(table1, table2)
local merged_table = table1 or {} -- Ensure a valid table, even if nil
for k, _ in pairs(table2) do
merged_table[k] = table2[k]
end
-- Return the merged table.
return merged_table
end
function M.debounce(ms, func)
local entry = { timer = nil, cancel = nil }
entry.timer = vim.uv.new_timer()
entry.timer:start(
ms,
0,
vim.schedule_wrap(function()
entry.cancel = func()
end)
)
return entry
end
-- https://github.com/hrsh7th/nvim-cmp/blob/main/lua/cmp/utils/api.lua
local api = {}
local CTRL_V = vim.api.nvim_replace_termcodes("<C-v>", true, true, true)
local CTRL_S = vim.api.nvim_replace_termcodes("<C-s>", true, true, true)
api.get_mode = function()
local mode = vim.api.nvim_get_mode().mode:sub(1, 1)
if mode == "i" then
return "i" -- insert
elseif mode == "v" or mode == "V" or mode == CTRL_V then
return "x" -- visual
elseif mode == "s" or mode == "S" or mode == CTRL_S then
return "s" -- select
elseif mode == "c" and vim.fn.getcmdtype() ~= "=" then
return "c" -- cmdline
end
end
api.is_insert_mode = function()
return api.get_mode() == "i"
end
---Check if cursor is in syntax group
---@param group string | []string
---@return boolean
M.in_syntax_group = function(group)
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
if not api.is_insert_mode() then
col = col + 1
end
for _, syn_id in ipairs(vim.fn.synstack(row, col)) do
syn_id = vim.fn.synIDtrans(syn_id) -- Resolve :highlight links
local g = vim.fn.synIDattr(syn_id, "name")
if type(group) == "string" and g == group then
return true
elseif type(group) == "table" and vim.tbl_contains(group, g) then
return true
end
end
return false
end
---Check if cursor is in treesitter capture
---@param capture string | []string
---@return boolean
M.in_treesitter_capture = function(capture)
local buf = vim.api.nvim_get_current_buf()
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
row = row - 1
if vim.api.nvim_get_mode().mode == "i" then
col = col - 1
end
local get_captures_at_pos = -- See neovim/neovim#20331
require("vim.treesitter").get_captures_at_pos -- for neovim >= 0.8 or require('vim.treesitter').get_captures_at_position -- for neovim < 0.8
local captures_at_cursor = vim.tbl_map(function(x)
return x.capture
end, get_captures_at_pos(buf, row, col))
if vim.tbl_isempty(captures_at_cursor) then
return false
elseif type(capture) == "string" and vim.tbl_contains(captures_at_cursor, capture) then
return true
elseif type(capture) == "table" then
for _, v in ipairs(capture) do
if vim.tbl_contains(captures_at_cursor, v) then
return true
end
end
end
return false
end
function M.shorten_path(path)
local sep = package.config:sub(1, 1)
local parts = {}
for part in path:gmatch("[^" .. sep .. "]+") do
table.insert(parts, part)
end
for i = 1, #parts - 2 do
parts[i] = parts[i]:sub(1, 1)
end
return table.concat(parts, "_")
end
return M

167
nvim/lua/largefiles.lua Normal file
View file

@ -0,0 +1,167 @@
local doau = require("funcs").doau
local maxline = require("funcs").maxline
local ifind = require("funcs").ifind
local pcall_notify = require("funcs").pcall_notify
local max_file_size = 2
local max_file_size_readonly = 100
local ignore_ft = {
"help",
"man",
"lspinfo",
"trouble",
"null-ls-info",
"qf",
"notify",
"startuptime",
"checkhealth",
"netrw",
"neotest-output",
"neotest-output-panel",
"neotest-summary",
"vista_kind",
"sagaoutline",
"httpResult",
}
local function get_buf_size(path)
local ok, stats = pcall(function()
return vim.uv.fs_stat(path)
end)
if not (ok and stats) then
return 0
end
return math.floor(0.5 + (stats.size / (1024 * 1024)))
end
local FILE_TYPE = {
NORMAL = 0,
LONG_LINE = 1,
LARGE_SIZE = 2,
READ_ONLY = 3,
}
local function is_large_file(bufnr, as_bool, path)
local function wrap()
if not bufnr then
return false
end
local ok, large_buf = pcall(vim.api.nvim_buf_get_var, bufnr, "large_buf")
if not ok then
large_buf = nil
end
if large_buf ~= nil then
return large_buf
end
local _type = FILE_TYPE.NORMAL
vim.api.nvim_buf_set_var(bufnr, "large_buf", _type)
if ifind(ignore_ft, function(item, _)
return vim.bo.ft == item
end) then
return _type
end
bufnr = bufnr or vim.api.nvim_get_current_buf()
path = path or vim.api.nvim_buf_get_name(bufnr)
local size = get_buf_size(path)
if size > max_file_size_readonly then
vim.notify("LARGE FILE SIZE: READONLY " .. size, vim.log.levels.INFO)
_type = FILE_TYPE.READ_ONLY
elseif size > max_file_size then
vim.notify("LARGE FILE SIZE " .. size, vim.log.levels.INFO)
_type = FILE_TYPE.LARGE_SIZE
else
local _m = maxline(path)
if _m > vim.o.synmaxcol then
vim.notify("LONG LINE " .. _m, vim.log.levels.INFO)
_type = FILE_TYPE.LONG_LINE
end
end
if _type ~= FILE_TYPE.NORMAL then
vim.api.nvim_buf_set_var(bufnr, "large_buf", _type)
doau("LargeFile", {})
end
return _type
end
local _t = wrap()
if not as_bool then
return _t
end
return _t ~= FILE_TYPE.NORMAL
end
local function optimize_buffer(bufnr, path)
local status_ok, _ = pcall(vim.api.nvim_buf_get_var, bufnr, "large_buf")
if status_ok then
return
end
local _type = is_large_file(bufnr, false, path)
if _type == FILE_TYPE.NORMAL then
return
end
vim.opt_local.cursorline = false
vim.opt_local.linebreak = false
vim.opt_local.wrap = false
vim.opt_local.spell = false
vim.opt_local.hlsearch = false
vim.opt_local.incsearch = false
vim.opt_local.foldmethod = "manual"
vim.opt_local.foldenable = false
vim.opt_local.foldcolumn = "0"
vim.opt_local.swapfile = false
vim.opt_local.bufhidden = "unload"
vim.opt_local.relativenumber = false
vim.b.numbertoggle_disabled = 1
vim.b.matchup_matchparen_fallback = 0
vim.b.matchup_matchparen_enabled = 0
if _type == FILE_TYPE.LONG_LINE then
vim.opt_local.list = false
vim.opt_local.undolevels = -1
vim.opt_local.undofile = false
end
-- pcall_notify(function()
-- require("rainbow-delimiters").disable(bufnr)
-- end)
pcall_notify(function()
require("ufo").detach(bufnr)
end)
pcall_notify(function()
require("gitsigns.attach").detach(bufnr)
end)
pcall_notify(function()
require("local-highlight").detach(bufnr)
end)
-- pcall_notify(function()
-- require('smear_cursor').enabled = false
-- end)
if _type == FILE_TYPE.READ_ONLY then
vim.opt_local.buftype = "nowrite"
end
end
return {
is_large_file = is_large_file,
FILE_TYPE = FILE_TYPE,
optimize_buffer = optimize_buffer,
}

View file

@ -0,0 +1,197 @@
-- https://github.com/deathbeam/myplugins.nvim/blob/main/lua/myplugins
local group = vim.api.nvim_create_augroup("native-completion", { clear = true })
local funcs = require("funcs")
local config = {
-- entry_mapper = function(vim_item, client)
-- local entry = {
-- source = {
-- source = {
-- client = client,
-- }
-- }
-- }
-- entry.get_completion_item = function(self)
-- return {
-- label = vim_item.abbr,
-- abbr = vim_item.abbr,
-- kind = vim_item.kind,
-- menu = vim_item.menu,
-- icase = vim_item.icase,
-- dup = vim_item.dup,
-- empty = vim_item.empty,
-- detail = vim_item.menu,
-- }
-- end
-- local highlights_info = require("colorful-menu").cmp_highlights(entry)
-- vim.print(highlights_info)
-- if highlights_info ~= nil then
-- vim_item.abbr_hl_group = highlights_info.highlights
-- vim_item.abbr = highlights_info.text
-- end
-- return vim_item
-- end,
debounce_delay = 200,
}
local function complete_changed(args)
local methods = vim.lsp.protocol.Methods
if not string.find(vim.o.completeopt, "popup") then
return
end
if not vim.v.event or not vim.v.event.completed_item then
return
end
local cur_item = vim.v.event.completed_item
local cur_info = vim.fn.complete_info()
local selected = cur_info.selected
funcs.debounce(config.debounce_delay, function()
local completion_item = vim.tbl_get(cur_item or {}, "user_data", "nvim", "lsp", "completion_item")
if not completion_item then
return
end
-- vim.print(methods.completionItem_resolve)
local _, cancel = vim.lsp.buf_request(
args.buf,
methods.completionItem_resolve,
---@param client vim.lsp.Client
function(client, buf)
if not client:supports_method(methods.completionItem_resolve, buf) then
return
end
return completion_item
end,
vim.schedule_wrap(function(err, item)
if err or not item then
return
end
local docs = vim.tbl_get(item, "documentation", "value")
if not docs or #docs == 0 then
return
end
local wininfo = vim.api.nvim__complete_set(selected, { info = docs })
if not wininfo.winid or not wininfo.bufnr then
return
end
vim.api.nvim_win_set_config(wininfo.winid, {
---@diagnostic disable-next-line: assign-type-mismatch
border = vim.o.winborder,
focusable = false,
})
vim.treesitter.start(wininfo.bufnr, "markdown")
vim.wo[wininfo.winid].conceallevel = 3
vim.wo[wininfo.winid].concealcursor = "niv"
end),
function() end
)
return cancel
end)
end
local M = {}
M.attach_completion = function(client, buf)
if not vim.lsp.completion or not vim.lsp.completion.enable then
return
end
if not client:supports_method(vim.lsp.protocol.Methods.textDocument_completion, buf) then
return
end
if client.name == "minuet" then
return
end
vim.api.nvim_create_autocmd("CompleteChanged", {
group = group,
desc = "Auto show LSP documentation",
callback = complete_changed,
buffer = buf,
})
vim.lsp.completion.enable(true, client.id, buf, {
autotrigger = true,
convert = function(item)
local doc = item.documentation or {}
local info
if vim.bo.filetype == "c" then
info = ("%s%s\n \n%s"):format(item.detail or "", item.label, doc.value or "")
end
local entry = {
abbr = item.label,
kind = vim.lsp.protocol.CompletionItemKind[item.kind] or "Unknown",
menu = item.detail or "",
icase = 1,
dup = 0,
empty = 0,
info = info and info:gsub("\n+%s*\n$", "") or nil,
}
if config.entry_mapper then
return config.entry_mapper(entry, client)
end
return entry
end,
})
end
-- cmdcompletion
local function cmdcmp()
if vim.fn.has("nvim-0.11.0") == 0 then
return
end
local term = vim.api.nvim_replace_termcodes("<C-@>", true, true, true)
vim.cmd([[set wildcharm=<C-@>]])
vim.opt.wildmenu = true
vim.opt.wildmode = "noselect:lastused,full"
vim.keymap.set("c", "<Up>", "<End><C-U><Up>", { silent = true })
vim.keymap.set("c", "<Down>", "<End><C-U><Down>", { silent = true })
vim.api.nvim_create_autocmd("CmdlineChanged", {
group = group,
desc = "Auto show command line completion",
pattern = ":",
callback = function()
local cmdline = vim.fn.getcmdline()
local curpos = vim.fn.getcmdpos()
local last_char = cmdline:sub(curpos - 1, curpos - 1)
if
curpos == #cmdline + 1
and vim.fn.pumvisible() == 0
and last_char:match("[%w%/%:- ]")
and not cmdline:match("^%d+$")
then
vim.api.nvim_feedkeys(term, "ti", false)
vim.opt.eventignore:append("CmdlineChanged")
vim.schedule(function()
vim.fn.setcmdline(vim.fn.substitute(vim.fn.getcmdline(), "\\%x00", "", "g"))
vim.opt.eventignore:remove("CmdlineChanged")
end)
end
end,
})
end
-- vim.api.nvim_create_autocmd({ "CmdlineEnter" }, {
-- once = true,
-- callback = cmdcmp,
-- })
return M

87
nvim/lua/lsp/init.lua Normal file
View file

@ -0,0 +1,87 @@
--
-- https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md
local M = {}
M.lsps = {
-- "nginx_language_server",
"nixd",
"lua_ls",
"rust_analyzer",
"bashls",
"vimls",
"html",
"cssls",
-- "jedi_language_server",
"ruff",
"ty",
"basedpyright",
"taplo",
"ts_ls",
"neocmake",
"docker_language_server",
"biome",
"jinja_lsp",
"golangci_lint_ls",
"gopls",
"vacuum",
"yamlls",
"jsonls",
"clangd",
}
M.setup = function()
for _, lsp in ipairs(M.lsps) do
local cfg = vim.lsp.config[lsp]
if not cfg then
vim.print(string.format("%s not configured", lsp))
goto continue
end
local cmd = cfg.cmd
if cmd == nil then
vim.print(string.format("%s not configured: cmd nil", lsp))
goto continue
end
if type(cmd) == "function" then
vim.lsp.enable(lsp, vim.g.lsp_autostart)
goto continue
end
if cmd ~= nil and vim.fn.executable(cmd[1]) == 1 then
vim.lsp.enable(lsp, vim.g.lsp_autostart)
end
::continue::
end
-- vim.lsp.handlers["workspace/diagnostic/refresh"] = function(_, _, ctx)
-- local ns = vim.lsp.diagnostic.get_namespace(ctx.client_id)
-- local bufnr = vim.api.nvim_get_current_buf()
-- vim.diagnostic.reset(ns, bufnr)
-- return true
-- end
vim.diagnostic.config({
underline = true,
signs = true,
virtual_text = false,
virtual_lines = { current_line = true },
float = true,
-- jump = {
-- float = true,
-- wrap = true,
-- },
update_in_insert = false,
severity_sort = true,
})
vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, {
update_in_insert = false,
})
require("lsp.utils").setup_autocmds()
end
return M

334
nvim/lua/lsp/utils.lua Normal file
View file

@ -0,0 +1,334 @@
local is_large_file = require("largefiles").is_large_file
local methods = vim.lsp.protocol.Methods
local opts_l = { silent = true, noremap = true }
local M = {}
M.keys = {
{
"<leader>sd",
function()
require("fzf-lua").lsp_definitions({ multiprocess = true })
end,
{ desc = "Search: Definitions", table.unpack(opts_l) },
},
{
"<leader>sS",
function()
require("fzf-lua").lsp_live_workspace_symbols({ multiprocess = true })
end,
{ desc = "Search: Symbols", table.unpack(opts_l) },
},
{
"grr",
function()
require("fzf-lua").lsp_references({ multiprocess = true, ignore_current_line = true })
end,
{ desc = "Search: references", table.unpack(opts_l) },
},
{
"gd",
vim.lsp.buf.definition,
{ desc = "GoTo: definition", table.unpack(opts_l) },
},
{
"gD",
vim.lsp.buf.declaration,
{ desc = "GoTo: declarations", table.unpack(opts_l) },
},
{
"K",
vim.lsp.buf.hover,
{ silent = true, desc = "Lang: hover doc", table.unpack(opts_l) },
},
{
"grn",
vim.lsp.buf.rename,
{ desc = "Lang: rename", table.unpack(opts_l) },
},
{
"gE",
vim.diagnostic.open_float,
{ desc = "Lang: diagnistic", table.unpack(opts_l) },
},
{
"]d",
function()
vim.diagnostic.jump({ count = vim.v.count1 })
end,
{ desc = "Jump to the next diagnostic in the current buffer", table.unpack(opts_l) },
},
{
"[d",
function()
vim.diagnostic.jump({ count = -vim.v.count1 })
end,
{ desc = "Jump to the previous diagnostic in the current buffer", table.unpack(opts_l) },
},
{
"]e",
function()
vim.diagnostic.jump({ count = vim.v.count1, severity = vim.diagnostic.severity.ERROR })
end,
{ desc = "Jump to the next ERROR diagnostic in the current buffer", table.unpack(opts_l) },
},
{
"[e",
function()
vim.diagnostic.jump({ count = -vim.v.count1, severity = vim.diagnostic.severity.ERROR })
end,
{ desc = "Jump to the previous ERROR diagnostic in the current buffer", table.unpack(opts_l) },
},
}
local inlay_hints_group = vim.api.nvim_create_augroup("toggle_inlay_hints", { clear = false })
local function toggle_inlay_hints(bufnr)
if bufnr == nil then
bufnr = vim.api.nvim_get_current_buf()
end
local enabled = vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr })
if not enabled then
vim.api.nvim_create_autocmd("InsertEnter", {
group = inlay_hints_group,
desc = "Enable inlay hints",
buffer = bufnr,
callback = function()
vim.lsp.inlay_hint.enable(false, { bufnr = bufnr })
end,
})
vim.api.nvim_create_autocmd("InsertLeave", {
group = inlay_hints_group,
desc = "Disable inlay hints",
buffer = bufnr,
callback = function()
vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })
end,
})
else
vim.api.nvim_clear_autocmds({
buffer = bufnr,
group = inlay_hints_group,
})
end
vim.lsp.inlay_hint.enable(not enabled, { bufnr = bufnr })
end
--- https://github.com/neovim/nvim-lspconfig/blob/f4619ab31fc4676001ea05ae8200846e6e7700c7/plugin/lspconfig.lua#L123
--- Sets up LSP keymaps and autocommands for the given buffer.
---@param client vim.lsp.Client
---@param bufnr integer
function M.on_attach(client, bufnr)
if is_large_file(bufnr, true) then
vim.bo[bufnr].tagfunc = nil
return 0
end
if client:supports_method(methods.textDocument_inlayHint, bufnr) then
vim.keymap.set(
{ "n" },
"<leader>ti",
toggle_inlay_hints,
{ buffer = bufnr, silent = true, desc = "Toggle Inlay hint", noremap = true }
)
toggle_inlay_hints(bufnr)
end
if client.name == "phoenix" or vim.b[bufnr].lsp_keymaps_set == 1 then
return 1
end
local prev_keymaps = {}
for _, keymap in ipairs(M.keys) do
local name = keymap[1]
if #keymap == 3 then
table.insert(keymap, 1, "n")
end
if type(keymap[2]) == "table" then
for _, mode in ipairs(keymap[2]) do
table.insert(prev_keymaps, vim.fn.maparg(name, mode, false, true))
end
else
table.insert(prev_keymaps, vim.fn.maparg(name, keymap[2], false, true))
end
keymap[4].buffer = bufnr
vim.keymap.set(table.unpack(keymap))
end
if client:supports_method(methods.textDocument_codeAction, bufnr) then
table.insert(prev_keymaps, vim.fn.maparg("gra", "n", false, true))
table.insert(prev_keymaps, vim.fn.maparg("gra", "v", false, true))
vim.keymap.set({ "n", "v" }, "gra", function()
require("fzf-lua").lsp_code_actions({
winopts = {
relative = "cursor",
width = 0.6,
height = 0.6,
row = 1,
preview = { vertical = "up:70%" },
},
})
end, { desc = "Code actions", silent = true })
end
vim.api.nvim_create_autocmd("LspDetach", {
buffer = bufnr,
callback = function()
for _, keymap in ipairs(prev_keymaps) do
pcall(vim.fn.mapset, keymap)
end
vim.b[bufnr].lsp_keymaps_set = 0
end,
})
if not client:supports_method(methods.textDocument_hover, bufnr) then
client.server_capabilities.hoverProvider = false
end
-- vim.bo[bufnr].omnifunc = "v:lua.vim.lsp.omnifunc"
vim.b[bufnr].lsp_keymaps_set = 1
return 1
end
local capabilities = vim.lsp.protocol.make_client_capabilities()
-- copy from blink.cmp
capabilities.textDocument = {
foldingRange = {
dynamicRegistration = false,
lineFoldingOnly = true,
},
completion = {
dynamicRegistration = false,
completionItem = {
snippetSupport = true,
commitCharactersSupport = false, -- todo:
documentationFormat = { "markdown", "plaintext" },
deprecatedSupport = true,
preselectSupport = false, -- todo:
tagSupport = { valueSet = { 1 } }, -- deprecated
insertReplaceSupport = true, -- todo:
resolveSupport = {
properties = {
"documentation",
"detail",
"additionalTextEdits",
"command",
"data",
},
},
insertTextModeSupport = {
-- todo: support adjustIndentation
valueSet = { 1 }, -- asIs
},
labelDetailsSupport = true,
},
contextSupport = true,
insertTextMode = 1,
completionList = {
itemDefaults = {
"commitCharacters",
"editRange",
"insertTextFormat",
"insertTextMode",
"data",
},
},
},
}
vim.lsp.config("*", {
capabilities = capabilities,
root_markers = vim.g.root_pattern,
})
local group = vim.api.nvim_create_augroup("my-lsp-config", { clear = true })
M.setup_autocmds = function()
vim.api.nvim_create_autocmd("LspAttach", {
group = group,
desc = "attach lsp event",
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
if not client then
return
end
if vim.b[args.buf].lsp_attached == nil then
vim.b[args.buf].lsp_attached = {}
elseif vim.b[args.buf].lsp_attached[client.id] ~= nil then
return
end
client.server_capabilities.semanticTokensProvider = nil
local attached = M.on_attach(client, args.buf)
if not attached then
local out = vim.lsp.buf_detach_client(args.buf, client.id)
if out then
vim.b[args.buf].lsp_attached[client.id] = nil
end
end
vim.b[args.buf].lsp_attached[client.id] = 1
if not client:supports_method(vim.lsp.protocol.Methods.textDocument_completion, args.buf) then
return
end
local chars = client.server_capabilities.completionProvider.triggerCharacters
if chars then
for i = string.byte("a"), string.byte("z") do
if not vim.list_contains(chars, string.char(i)) then
table.insert(chars, string.char(i))
end
end
for i = string.byte("A"), string.byte("Z") do
if not vim.list_contains(chars, string.char(i)) then
table.insert(chars, string.char(i))
end
end
end
-- require("lsp.autocomplete").attach_completion(client, args.buf)
end,
})
local timer = nil --[[uv_timer_t]]
local function reset_timer()
if timer then
timer:stop()
timer:close()
end
timer = nil
end
vim.api.nvim_create_autocmd("LspDetach", {
group = group,
desc = "Auto stop client when no buffer atttached",
callback = function(args)
local client_id = args.data.client_id
local client = vim.lsp.get_clients({ client_id = client_id })[1]
if not client or not vim.tbl_isempty(client.attached_buffers) then
return
end
reset_timer()
timer = assert(vim.loop.new_timer())
timer:start(200, 0, function()
reset_timer()
vim.schedule(function()
vim.lsp.stop_client(client_id, true)
end)
end)
end,
})
end
return M

View file

@ -0,0 +1,53 @@
local M = {}
M.modify_config = function(cfg)
cfg.provider = "airun"
cfg.mode = "legacy"
cfg.auto_suggestions_provider = "airun_autocomplete"
cfg.providers.airun = {
__inherited_from = "openai",
endpoint = vim.g.airun_endpoint,
api_key_name = "AI_RUN_TOKEN",
model = vim.g.airun_model,
disable_tools = true,
allow_insecure = true,
extra = {
temperature = 0.7,
max_tokens = 512,
},
}
cfg.providers.airun_autocomplete = {
__inherited_from = "openai",
endpoint = vim.g.airun_endpoint,
allow_insecure = true,
api_key_name = "AI_RUN_TOKEN",
model = vim.g.airun_autocomplete_model,
disable_tools = true,
}
cfg.rag_service.enabled = true
cfg.rag_service.llm = {
provider = "airun",
endpoint = vim.g.airun_endpoint,
allow_insecure = true,
api_key = "AI_RUN_TOKEN",
model = vim.g.airun_model,
extra = {
temperature = 0.7,
max_tokens = 512,
},
}
cfg.rag_service.embed = {
provider = "airun",
endpoint = vim.g.airun_endpoint,
allow_insecure = true,
api_key = "AI_RUN_TOKEN",
model = vim.g.ai_run_embedded_model,
extra = {
embed_batch_size = 16,
},
}
return cfg
end
return M

View file

@ -0,0 +1,93 @@
return {
"yetone/avante.nvim",
event = vim.g.post_load_events,
-- from nix
dev = true,
opts = {
mode = "agentic",
debug = false,
providers = {},
web_search_engine = {},
behaviour = {
auto_focus_sidebar = true,
auto_suggestions = false,
auto_suggestions_respect_ignore = false,
auto_set_highlight_group = true,
auto_set_keymaps = true,
auto_apply_diff_after_generation = false,
jump_result_buffer_on_finish = false,
support_paste_from_clipboard = true,
minimize_diff = true,
enable_token_counting = true,
use_cwd_as_project_root = true,
auto_focus_on_diff_view = true,
},
hints = { enabled = true },
rag_service = { -- RAG Service configuration
enabled = false,
host_mount = os.getenv("HOME"),
runner = "nix", -- Runner for the RAG service (can use docker or nix)
docker_extra_args = "",
},
mappings = {
suggestion = {
accept = "<Tab>",
next = "<M-]>",
prev = "<M-[>",
dismiss = "<C-]>",
},
diff = {
ours = "gH",
theirs = "gh",
all_theirs = "gA",
both = "gB",
cursor = "gc",
next = "]x",
prev = "[x",
},
},
repo_map = {
ignore_patterns = {
"%.git",
"%.worktree",
"__pycache__",
"node_modules",
"target",
"build",
"dist",
"BUILD",
"ventor%.",
"%.min%.",
".devenv",
}, -- ignore files matching these
negate_patterns = {}, -- negate ignore files matching these.
},
selector = {
provider = "fzf_lua",
},
},
dependencies = {
"nvim-treesitter/nvim-treesitter",
"nvim-lua/plenary.nvim",
"MunifTanjim/nui.nvim",
{
-- from nix
dev = true,
"Kaiser-Yang/blink-cmp-avante",
},
"ibhagwan/fzf-lua", -- for file_selector provider fzf
},
config = function(_, opts)
require("avante_lib").load()
opts = require("plugins.ai.avante.airun").modify_config(opts)
-- opts = require("plugins.ai.avante.ollama").modify_config(opts)
require("avante").setup(opts)
end,
}

View file

@ -0,0 +1,35 @@
local M = {}
local model = "hf.co/mradermacher/Qwen2.5-CoderX-14B-v0.5-GGUF:Q8_0"
M.modify_config = function(cfg)
cfg.provider = "ollama"
cfg.providers.ollama = {
endpoint = vim.g.ollama_url,
model = model,
disabled_tools = { "python" },
extra_request_body = {
-- num_ctx = 1024 * 20,
temperature = 0.5,
},
}
cfg.rag_service.llm = {
provider = "ollama",
endpoint = vim.g.ollama_url,
api_key = "",
model = "phi4-mini:latest",
extra = nil,
}
cfg.rag_service.embed = {
provider = "ollama",
endpoint = vim.g.ollama_url,
api_key = "",
model = "nomic-embed-text:latest",
extra = {
embed_batch_size = 10,
},
}
return cfg
end
return M

View file

@ -0,0 +1,99 @@
local M = {
opts = {
allow_insecure = true,
show_defaults = false,
},
}
M.gemini = function()
return require("codecompanion.adapters").extend("gemini", {
env = {
api_key = "GEMINI_API_KEY",
},
})
end
M.airun = function()
return require("codecompanion.adapters").extend("openai_compatible", {
env = {
url = vim.g.airun_url,
api_key = "AI_RUN_TOKEN", -- optional: if your endpoint is authenticated
chat_url = "/v1/chat/completions", -- optional: default value, override if different
-- models_endpoint = "/v1/models", -- optional: attaches to the end of the URL to form the endpoint to retrieve models
},
schema = {
model = {
default = vim.g.airun_model,
choices = function(self)
return {}
end,
},
-- num_ctx = {
-- default = 131072,
-- },
},
})
end
local function ollama_params(model_name, model)
return function()
return require("codecompanion.adapters").extend("ollama", {
env = {
url = vim.g.ollama_url,
},
headers = {
["Content-Type"] = "application/json",
},
parameters = {
sync = true,
keep_alive = "30m",
},
name = model_name,
schema = {
model = {
default = model,
},
num_ctx = {
default = 1024 * 32, -- 32768
},
temperature = {
default = 0.5,
},
},
})
end
end
local function ollama_modify(model_name, model, func)
local params_func = ollama_params(model_name, model)
return function()
local params = params_func()
return func(params)
end
end
M.ollama_deepseek = ollama_params("deepseek-r1", "deepseek-r1:14b-qwen-distill-q4_K_M")
M.ollama_deepcode = ollama_params("deepcode", "hf.co/lmstudio-community/DeepCoder-14B-Preview-GGUF:Q4_K_M")
M.ollama_gemma3 = ollama_params("gemma3", "hf.co/unsloth/gemma-3-12b-it-GGUF:Q4_K_M")
M.ollama_codegemma = ollama_params("codegemma", "codegemma:latest")
M.ollama_phimini = ollama_params("phimini", "phi4-mini:latest")
M.ollama_devstral = ollama_modify("devstral", "devstral:latest", function(params)
params.schema.temperature.default = 0.15
return params
end)
local function ollama_qwen(model_name, model)
return ollama_modify(model_name, model, function(params)
return params
end)
end
M.ollama_qwencoder = ollama_qwen("qwen2.5", "hf.co/unsloth/Qwen2.5-Coder-7B-Instruct-128K-GGUF:Q4_K_M")
M.ollama_qwen = ollama_qwen("qwen3", "hf.co/unsloth/Qwen3-8B-128K-GGUF:Q6_K_XL")
M.ollama_qwenamall = ollama_qwen("qwen3-small", "qwen3:0.6b")
M.ollama_qwenlarge = ollama_qwen("qwen3-large", "qwen3:30b-a3b")
M.default_adapter = M.airun
return M

View file

@ -0,0 +1,106 @@
-- lua/plugins/codecompanion/fidget-spinner.lua
-- This module manages fidget spinner progress indicators for CodeCompanion requests.
local M = {}
-- Initializes the fidget spinner module by setting up autocommands.
function M:init()
local group = vim.api.nvim_create_augroup("CodeCompanionFidgetHooks", {})
-- Autocommand to handle when a CodeCompanion request starts.
vim.api.nvim_create_autocmd({ "User" }, {
pattern = "CodeCompanionRequestStarted",
group = group,
callback = function(request)
if not request.data.strategy then
return
end
local handle = M:create_progress_handle(request) -- Create progress handle for the request
M:store_progress_handle(request.data.id, handle) -- Store the progress handle
end,
})
-- Autocommand to handle when a CodeCompanion request finishes.
vim.api.nvim_create_autocmd({ "User" }, {
pattern = "CodeCompanionRequestFinished",
group = group,
callback = function(request)
local handle, duration = M:pop_progress_handle(request.data.id) -- Pop the progress handle and get duration
if handle then
M:report_exit_status(handle, request, duration) -- Report the exit status of the request
handle:finish() -- Finish the progress handle
end
end,
})
end
-- Table to store progress handles, indexed by request ID.
M.handles = {}
-- Table to store start times of requests, indexed by request ID.
M.start_times = {}
-- Stores a progress handle and the start time for a given request ID.
function M:store_progress_handle(id, handle)
M.handles[id] = handle -- Store handle with request ID
M.start_times[id] = vim.uv.hrtime() -- Record start time
end
-- Pops (removes and returns) a progress handle and calculates the duration of the request.
function M:pop_progress_handle(id)
local handle = M.handles[id] -- Get handle from stored handles
local start_time = M.start_times[id] -- Get start time from stored start times
M.handles[id] = nil -- Remove handle after popping
M.start_times[id] = nil -- Remove start time after popping
local duration = nil
if start_time then
local elapsed_ns = vim.uv.hrtime() - start_time
duration = string.format("%.2fs", elapsed_ns / 1e9) -- Calculate duration in seconds
end
return handle, duration
end
-- Creates a progress handle with a dynamic title based on the request strategy and adapter.
function M:create_progress_handle(request)
local progress = require("fidget.progress")
return progress.handle.create({
title = " Requesting assistance (" .. request.data.strategy .. ")", -- Title includes strategy
message = "In progress...",
lsp_client = {
name = M:llm_role_title(request.data.adapter), -- LSP client name based on adapter
},
})
end
-- Generates a formatted title for the LSP client based on the adapter information.
function M:llm_role_title(adapter)
local parts = {}
table.insert(parts, adapter.formatted_name) -- Insert formatted adapter name
if adapter.model and adapter.model ~= "" then
table.insert(parts, "(" .. adapter.model .. ")") -- Insert model name if available
end
return table.concat(parts, " ") -- Concatenate parts to create title
end
-- Reports the exit status of a request to the progress handle, including duration if available.
function M:report_exit_status(handle, request, duration)
local message = ""
if request.data.status == "success" then
message = "Completed"
elseif request.data.status == "error" then
message = " Error"
else
message = "󰜺 Cancelled"
end
if duration then
message = message .. " (" .. duration .. ")" -- Append duration to message if available
end
handle.message = message -- Update progress handle message
end
return M

View file

@ -0,0 +1,232 @@
local adapters = require("plugins.ai.codecompanion.adapters")
return {
"olimorris/codecompanion.nvim",
-- from nix
dev = true,
cmd = {
"CodeCompanionChat",
"CodeCompanion",
"CodeCompanionCmd",
"CodeCompanionActions",
"CodeCompanionHistory",
},
keys = {
{
"<leader>cc",
function()
require("codecompanion").toggle()
end,
desc = "Code Companion",
silent = true,
},
{
"<leader>cc",
":'<,'>CodeCompanionChat Add<cr>",
desc = "Code Companion Add",
silent = true,
mode = "x",
noremap = true,
},
{
"<C-?>",
function()
require("codecompanion").toggle()
end,
desc = "Code Companion",
silent = true,
},
{
"<C-?>",
":'<,'>CodeCompanionChat Add<cr>",
desc = "Code Companion Add",
silent = true,
mode = "x",
noremap = true,
},
{
"<leader>ci",
":CodeCompanion<cr>",
desc = "Code Companion inline",
silent = true,
mode = "n",
noremap = true,
},
{
"<leader>ci",
":'<,'>CodeCompanion<cr>",
desc = "Code Companion inline",
silent = true,
mode = "x",
noremap = true,
},
{
"<leader>ca",
":'<,'>CodeCompanionActions<cr>",
desc = "Code Companion Actions",
silent = true,
mode = "x",
noremap = true,
},
{
"<leader>ca",
":CodeCompanionActions<cr>",
desc = "Code Companion Actions",
silent = true,
mode = "n",
noremap = true,
},
{
"<leader>ch",
":CodeCompanionHistory<cr>",
desc = "Code Companion Actions",
silent = true,
mode = "n",
noremap = true,
},
},
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-treesitter/nvim-treesitter",
"j-hui/fidget.nvim",
{
"ravitemer/codecompanion-history.nvim",
-- from nix
dev = true,
},
{
"Davidyz/VectorCode",
-- lazy = true,
-- from nix
dev = true,
dependencies = { "nvim-lua/plenary.nvim" },
opts = {
async_opts = {
notify = true,
},
},
init = function()
vim.api.nvim_create_autocmd("LspAttach", {
callback = function()
local bufnr = vim.api.nvim_get_current_buf()
local cacher = require("vectorcode.config").get_cacher_backend()
require("vectorcode.cacher").utils.async_check("config", function()
cacher.register_buffer(bufnr, {
n_query = 10,
})
end, nil)
end,
desc = "Register buffer for VectorCode",
})
end,
config = function(_, opts)
require("vectorcode").setup(opts)
end,
},
},
init = function()
require("plugins.ai.codecompanion.fidget-spinner"):init()
end,
config = function()
local opts = {
adapters = adapters,
strategies = {
chat = {
adapter = "default_adapter",
keymaps = require("plugins.ai.codecompanion.keymaps"),
},
inline = {
adapter = "default_adapter",
keymaps = {
accept_change = {
modes = { n = "gh" },
description = "Accept the suggested change",
},
reject_change = {
modes = { n = "gH" },
description = "Reject the suggested change",
},
},
},
agent = { adapter = "default_adapter" },
},
display = {
chat = {
-- window = {
-- layout = "float",
-- },
icons = {
pinned_buffer = "📌 ",
watched_buffer = "👀 ",
},
show_header_separator = true,
show_settings = true,
},
},
opts = {
-- system_prompt = require("plugins.ai.codecompanion.system_prompt"),
},
prompt_library = require("plugins.ai.codecompanion.prompts"),
extensions = {
history = {
enabled = true,
opts = {
keymap = "<leader>sh",
save_chat_keymap = "sc",
auto_save = true,
expiration_days = 0,
picker = "fzf-lua",
auto_generate_title = false,
---On exiting and entering neovim, loads the last chat on opening chat
continue_last_chat = false,
---When chat is cleared with `gx` delete the chat from history
delete_on_clearing_chat = true,
---Directory path to save the chats
dir_to_save = vim.fn.stdpath("data") .. "/codecompanion-history",
---Enable detailed logging for history extension
enable_logging = false,
},
},
},
}
local ok, _ = pcall(require, "mchup")
if ok then
opts.extensions.mcphub = {
callback = "mcphub.extensions.codecompanion",
opts = {
make_vars = true,
make_slash_commands = true,
show_result_in_chat = true,
},
}
end
ok, _ = pcall(require, "vectorcode")
if ok then
opts.extensions.vectorcode = {
opts = {
tool_group = {
enabled = true,
extras = {},
collapse = false,
},
tool_opts = {
ls = {},
vectorise = {},
query = {
max_num = { chunk = -1, document = -1 },
default_num = { chunk = 50, document = 10 },
include_stderr = false,
use_lsp = true,
no_duplicate = true,
chunk_mode = false,
},
},
},
}
end
require("codecompanion").setup(opts)
end,
}

View file

@ -0,0 +1,140 @@
return {
options = {
modes = {
n = "?",
},
callback = "keymaps.options",
description = "Options",
hide = true,
},
completion = {
modes = {
i = "<C-_>",
},
index = 1,
callback = "keymaps.completion",
description = "Completion Menu",
},
send = {
modes = {
n = { "<CR>", "<C-s>" },
i = "<C-s>",
},
index = 1,
callback = "keymaps.send",
description = "Send",
},
regenerate = {
modes = {
n = "gr",
},
index = 2,
callback = "keymaps.regenerate",
description = "Regenerate the last response",
},
close = {
modes = {
n = "<C-c>",
i = "<C-c>",
},
index = 3,
callback = "keymaps.stop",
description = "Stop Chat",
},
stop = {
modes = {
n = "q",
},
index = 4,
callback = "keymaps.stop",
description = "Stop Request",
},
clear = {
modes = {
n = "gx",
},
index = 5,
callback = "keymaps.clear",
description = "Clear Chat",
},
codeblock = {
modes = {
n = "gc",
},
index = 6,
callback = "keymaps.codeblock",
description = "Insert Codeblock",
},
yank_code = {
modes = {
n = "gy",
},
index = 7,
callback = "keymaps.yank_code",
description = "Yank Code",
},
next_chat = {
modes = {
n = "}",
},
index = 8,
callback = "keymaps.next_chat",
description = "Next Chat",
},
previous_chat = {
modes = {
n = "{",
},
index = 9,
callback = "keymaps.previous_chat",
description = "Previous Chat",
},
next_header = {
modes = {
n = "]]",
},
index = 10,
callback = "keymaps.next_header",
description = "Next Header",
},
previous_header = {
modes = {
n = "[[",
},
index = 11,
callback = "keymaps.previous_header",
description = "Previous Header",
},
change_adapter = {
modes = {
n = "ga",
},
index = 12,
callback = "keymaps.change_adapter",
description = "Change adapter",
},
fold_code = {
modes = {
n = "za",
},
index = 13,
callback = "keymaps.fold_code",
description = "Fold code",
},
debug = {
modes = {
n = "gd",
},
index = 14,
callback = "keymaps.debug",
description = "View debug info",
},
system_prompt = {
modes = {
n = "gs",
},
index = 15,
callback = "keymaps.toggle_system_prompt",
description = "Toggle the system prompt",
},
}

View file

@ -0,0 +1,50 @@
local PROMPTS = {
["Comments"] = {
strategy = "inline",
description = "Add comments to not simplify ",
opts = {
modes = { "v" },
short_name = "comments",
auto_submit = true,
stop_context_insertion = true,
user_prompt = false,
},
prompts = {
{
role = "system",
content = function(context)
return "I want you to act as a expert of "
.. context.filetype
.. "\n"
.. [[
You must:
- Answer without ```
- Avoid wrapping the whole response in triple backticks.
]]
end,
},
{
role = "user",
content = function(context)
local text = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line)
return "I have the following code:\n\n```"
.. context.filetype
.. "\n"
.. text
.. "\n```\n Please add short comments on not simply cases.\n"
end,
opts = {
contains_code = true,
},
},
},
},
}
PROMPTS["Comments Ru"] = vim.deepcopy(PROMPTS["Comments"])
PROMPTS["Comments Ru"].opts.short_name = "comments_ru"
PROMPTS["Comments Ru"].prompts[2].content = function(context)
return PROMPTS["Comments"].prompts[2].content(context) .. "\n Ответь кратко на русском."
end
return PROMPTS

View file

@ -0,0 +1,37 @@
local PROMPTS = {
["Code Expert"] = {
strategy = "chat",
description = "Get some special advice from an LLM",
opts = {
modes = { "v" },
mapping = "<leader>cE",
short_name = "expert",
auto_submit = true,
stop_context_insertion = true,
user_prompt = true,
},
prompts = {
{
role = "system",
content = function(context)
return "I want you to act as a senior "
.. context.filetype
.. " developer. I will ask you specific questions and I want you to return concise explanations and codeblock examples."
end,
},
{
role = "user",
content = function(context)
local text = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line)
return "I have the following code:\n\n```" .. context.filetype .. "\n" .. text .. "\n```\n\n"
end,
opts = {
contains_code = true,
},
},
},
},
}
return PROMPTS

View file

@ -0,0 +1,8 @@
local funcs = require("funcs")
local prompts = {}
funcs.merge_tables(prompts, require("plugins.ai.codecompanion.prompts.comments"))
funcs.merge_tables(prompts, require("plugins.ai.codecompanion.prompts.expert"))
return prompts

View file

@ -0,0 +1,185 @@
return function(_)
local uname = vim.uv.os_uname()
local platform = string.format(
"sysname: %s, release: %s, machine: %s, version: %s",
uname.sysname,
uname.release,
uname.machine,
uname.version
)
-- Note: parallel tool execution is not supported by codecompanion currently
return string.format(
[[
You are an AI assistant plugged into user's code editor. Use the instructions below and the tools accessible to you for assisting the user.
# Role, tone and style
You should follow the user's requirements carefully and to the letter.
You should be more humanly likeable, and less like a computer. While you can have your own opinion and thoughts, you must stay focused, without deviating from the task at hand or the user's original requirements.
You should be concise, precise, direct, and to the point. Output text to communicate with the user; all text you output is displayed to the user. All non-code responses should respect the natural language the user is currently speaking.
You should respond in Github-flavored Markdown for formatting. Headings should start from level 3 (###) onwards.
You should wrap paths/URLs in backticks like `/path/to/file`. And you should always provide absolute path, or related path based on the current directory.
You should wrap any code related word/term with backticks like `function_name`.
IMPORTANT: You should NOT answer with unnecessary preamble or postamble, unless you're asked to. You should make every word meaningful. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request.
IMPORTANT: You should avoid all meaningless or irrelevant words. Please skip all obvious conclusions, explanations, or disclaimers, and offer deep-minded insights instead. This is fatal important when you're concluding, summarizing, or explaining something.
VERY IMPORTANT: SAY YOU DO NOT KNOW IF YOU DO NOT KNOW. DO NOT BE OVER CONFIDENT, ALWAYS BE CAUTIOUS.
VERY IMPORTANT: DO EXACTLY WHAT THE USER ASKS YOU TO DO, NOTHING MORE, NOTHING LESS, UNLESS YOU ARE TOLD TO DO SOMETHING DIFFERENT.
# Proactiveness
You are allowed to be proactive, but only when the user asks you to do something. You should strive to strike a balance between:
1. Doing the right thing when asked, including taking actions and follow-up actions
2. Not surprising the user with actions you take without asking. For example, if the user asks you how to approach something, you should do your best to answer their question first, and not immediately jump into taking actions.
3. Do not add additional code explanation summary unless requested by the user. After working on a file, just stop, rather than providing an explanation of what you did.
# Following conventions
When making changes to files, first understand the file's code conventions. Mimic code style, use existing libraries and utilities, and follow existing patterns.
- NEVER assume that a given library is available, even if it is well known. Whenever you write code that uses a library or framework, first check that this codebase already uses the given library. For example, you might look at neighboring files, or check the package.json (or cargo.toml, and so on depending on the language).
- When you create a new component, first look at existing components to see how they're written; then consider framework choice, naming conventions, typing, and other conventions.
- When you edit a piece of code, first look at the code's surrounding context (especially its imports) to understand the code's choice of frameworks and libraries. Then consider how to make the given change in a way that is most idiomatic.
- Always follow security best practices. Never introduce code that exposes or logs secrets and keys. Never commit secrets or keys to the repository.
- Consider cross-platform compatibility when suggesting solutions. Also consider performance where relevant. And maintainability is as fatal important. In all, please always follow the best practices of the programming language you're using, and write code like a senior developer. You may give advice about best practices to the user.
# Doing tasks
When the user asks you to do a task, the following steps are recommended:
1. Use tools you have permission to to understand the tasks and the user's queries. You are encouraged to use tools to gather information. But don't use tools if you can answer directly with your knowledge.
2. Implement the solution using all tools you have permission to.
3. Verify the solution if possible with tests. NEVER assume specific test framework or test script. Check the README or search codebase to determine the testing approach.
4. Prefer fetching context with tools you have permission to instead of historic messages since historic messages may be outdated, such as codes may be formatted by the editor.
NOTE: When you're reporting/concluding/summarizing/explaining something comes from the previous context, please using footnotes to refer to the references, such as the result of a tool invocation, or URLs, or files. You MUST give URLs if there're related URLs. Remember that you should output the list of footnotes before task execution. Examples:
<example>
The function `foo`. is used to do something.[^1]
...
It is sunny today.[^2]
[^1]: `<path/to/file>`, around function `foo`.
[^2]: https://url-to-weather-forecast.com
task execution if needed...
</example>
IMPORTANT: Before you begin work, think about what the code you're editing is supposed to do based on the filenames directory structure.
**VERY IMPORTANT**: You MUST ensure that all your decisions and actions are based on the known context only. Do not make assumptions, do not bias, avoid hallucination.
# Tool conventions
Before invoking tools, you should describe your purpose with: `I'm using **@<tool name>** to <action>", for <purpose>.`
Short descriptions of tools:
- `files`: read or edit files.
- `cmd_runner`: run shell commands.
- `nvim_runner`: run neovim commands or lua scripts. You can invoke neovim api by this tool.
IMPORTANT: In any situation, after an permission request, you MUST stop immediately and wait for approval.
IMPORTANT: In any situation, if user denies to execute a tool (that means they choose not to run the tool), you should ask for guidance instead of attempting another action. Do not try to execute over and over again. The user retains full control with an approval mechanism before execution.
**FATAL IMPORTANT**: YOU MUST EXECUTE ONLY **ONCE** AND ONLY **ONE TOOL** IN **ONE TURN**. That means you should STOP IMMEDIATELY after sending a tool invocation.
**FATAL IMPORTANT**: ***YOU MUST USE TOOLS STEP BY STEP, ONE BY ONE. THE RESULT OF EACH TOOL INVOCATION IS IN THE USER'S RESPONSE NEXT TURN. DO NOT PROCEED WITHOUT USER'S RESPONSE.*** KEEP THIS IN YOUR MIND!!!
## **Request Permissions to Tools**
Got the permission of a tool <==> User've told you how to invoke it.
Remember, you don't have any permission to tools by default. You cannot use tool without permission. You cannot get the permission of a tool by inferring how to invoke it implicitly from the context.
If you need a tool but you don't have permission to, request for permission with following format:
<example>
I need permission to use **@<tool name>** to <action>, for <purpose>.
</example>
**Once you got permission for a tool, please don't ask permission for it again.**
## Tool usage policy
1. When doing file operations, prefer to use `files` tool in order to reduce context usage.
2. When doing complex work like math calculations, prefer to use tools.
3. When searching or listing files, you should respect .gitignore patterns. Files like `target`, `node_modules`, `dist` etc should not be included, based on the context and gitignore.
# Tool usage general guidelines
To execute tools, you need to generate XML codeblocks mentioned below.
You should always try to save tokens for user while ensuring quality by minimizing the output of the tool, or you can combine multiple commands into one (which is recommended), such as `cd xxx && make`, or you can run actions sequentially (these actions must belong to the same tool) if the tool supports sequential execution. Running actions of a tool sequentially is considered to be one step/one tool invocation.
This is only a general usage guideline, the tool specific usage/guideline/arguments will be detailed once you got the permission to use the tool.
All tools share the same base XML structure:
<example>
~~~~xml
<tools>
<tool name="[tool_name]">
<action type="[action_type]">
[action specific elements]
</action>
</tool>
</tools>
~~~~
</example>
IMPORTANT: You should use "~~~~" instead of backticks to wrap the XML codeblock, since inner backticks may break the codeblock.
For example, if there is a tool called `example_tool` with an action called `example_action`, and the `example_action` has three elements: `<example_element_1>`, `<example_element_2>` and optional `<example_element_3>`, the XML structure would be:
<example>
~~~~xml
<tools>
<tool name="example_tool">
<action type="example_action">
<example_element_1>%s</example_element_1>
<example_element_2>%s</example_element_2>
</action>
</tool>
</tools>
~~~~
</example>
IMPORTANT: Some elements would need to wrap content in CDATA sections to protect special characters, while others do not need to be. Typically all string contents should be wrapped in CDATA sections, and numbers are not.
If the tool doesn't have an action type(usually when there's only one action in the tool), then it could be:
<example>
~~~~xml
<tools>
<tool name="example_tool">
<action type>
<example_element>%s</example_element>
</action>
</tool>
</tools>
~~~~
</example>
Some tools support sequential execution to execute multiple action in one XML codeblock:
<example>
~~~~xml
<tools>
<tool name="[tool_name]">
<action type="[action_type_1]">
[action specific elements]
</action>
<action type="[action_type_2]">
[action specific elements]
</action>
</tool>
</tools>
~~~~
</example>
IMPORTANT: Always return a XML markdown code block to run tools. Each operation should follow the XML schema exactly. XML must be valid.
IMPORTANT: Only tools with explicit sequential execution support are allowed to call multiple actions in one XML codeblock.
# Environment Awareness
- Platform: %s,
- Shell: %s,
- Current date: %s
- Current time: %s, timezone: %s(%s)
- Current working directory(git repo: %s): %s,
]],
"content1",
"<![CDATA[content2]]>",
"<![CDATA[content]]>",
platform,
vim.o.shell,
os.date("%Y-%m-%d"),
os.date("%H:%M:%S"),
os.date("%Z"),
os.date("%z"),
vim.fn.isdirectory(".git") == 1,
vim.fn.getcwd()
)
end

View file

@ -0,0 +1,131 @@
local config = require("codecompanion.config")
local helpers = require("codecompanion.strategies.chat.helpers")
local user_role = config.strategies.chat.roles.user
local api = vim.api
---Add a reference to the chat buffer
---@param chat CodeCompanion.Chat
---@param ref CodeCompanion.Chat.Ref
---@param row integer
local function add(chat, ref, row)
local lines = {}
table.insert(lines, string.format("> - %s", ref.id))
if vim.tbl_count(chat.refs) == 1 then
table.insert(lines, 1, "> Sharing:")
table.insert(lines, "")
end
api.nvim_buf_set_lines(chat.bufnr, row, row, false, lines)
end
---Parse the chat buffer to find where to add the references
---@param chat CodeCompanion.Chat
---@return table|nil
local function ts_parse_buffer(chat)
local query = vim.treesitter.query.get("markdown", "reference")
local tree = chat.parser:parse({ chat.header_line - 1, -1 })[1]
local root = tree:root()
-- Check if there are any references already in the chat buffer
local refs
for id, node in query:iter_captures(root, chat.bufnr, chat.header_line - 1, -1) do
if query.captures[id] == "refs" then
refs = node
end
end
if refs and not vim.tbl_isempty(chat.refs) then
local start_row, _, end_row, _ = refs:range()
return {
capture = "refs",
start_row = start_row + 2,
end_row = end_row + 1,
}
end
-- If not, check if there is a heading to add the references below
local role
local role_node
for id, node in query:iter_captures(root, chat.bufnr, chat.header_line - 1, -1) do
if query.captures[id] == "role" then
role = vim.treesitter.get_node_text(node, chat.bufnr)
role_node = node
end
end
role = helpers.format_role(role)
if role_node and role == user_role then
local start_row, _, end_row, _ = role_node:range()
return {
capture = "role",
start_row = start_row + 1,
end_row = end_row + 1,
}
end
return nil
end
---Add a reference to the chat buffer
---@param self CodeCompanion.Chat.References
---@param ref CodeCompanion.Chat.Ref
---@return nil
local function references_add(self, ref)
if not ref or not config.display.chat.show_references then
return self
end
local existed = false
if ref then
if not ref.opts then
ref.opts = {}
end
-- Ensure both properties exist with defaults
ref.opts.pinned = ref.opts.pinned or false
ref.opts.watched = ref.opts.watched or false
-- if the reference is already existing, replace it. or insert it
for i, existing_ref in pairs(self.Chat.refs) do
if existing_ref.id == ref.id then
self.Chat.refs[i] = ref
existed = true
end
end
if not existed then
table.insert(self.Chat.refs, ref)
end
-- If it's a buffer reference and it's being watched, start watching
if ref.bufnr and ref.opts.watched then
self.Chat.watchers:watch(ref.bufnr)
end
end
local parsed_buffer = ts_parse_buffer(self.Chat)
if parsed_buffer and not existed then
-- If the reference block already exists, add to it
if parsed_buffer.capture == "refs" then
add(self.Chat, ref, parsed_buffer.end_row - 1)
-- If there are no references then add a new block below the heading
elseif parsed_buffer.capture == "role" then
add(self.Chat, ref, parsed_buffer.end_row + 1)
end
end
end
---Add a reference to the chat buffer (Useful for user's adding custom Slash Commands)
---@param chat CodeCompanion.Chat
---@param data { role: string, content: string }
---@param source string
---@param id string
---@param opts? table Options for the message
return function(chat, data, source, id, opts)
opts = opts or { reference = id, visible = false }
references_add(chat.references, { source = source, id = id })
chat:add_message(data, opts)
end

View file

@ -0,0 +1,40 @@
local config = require("codecompanion.config")
local util = require("codecompanion.utils")
return function(chat, selected_adapter, selected_model)
local adapters = vim.deepcopy(config.adapters)
local current_adapter = chat.adapter.name
local current_model = vim.deepcopy(chat.adapter.schema.model.default)
if current_adapter ~= selected_adapter then
chat.adapter = require("codecompanion.adapters").resolve(adapters[selected_adapter])
util.fire("ChatAdapter", {
bufnr = chat.bufnr,
adapter = require("codecompanion.adapters").make_safe(chat.adapter),
})
chat.ui.adapter = chat.adapter
chat:apply_settings()
end
-- Update the system prompt
local system_prompt = config.opts.system_prompt
if type(system_prompt) == "function" then
if chat.messages[1] and chat.messages[1].role == "system" then
local opts = {
adapter = chat.adapter,
language = config.opts.language,
}
chat.messages[1].content = system_prompt(opts)
end
end
if current_model ~= selected_model then
util.fire("ChatModel", {
bufnr = chat.bufnr,
model = selected_model,
})
end
chat:apply_model(selected_model)
chat:apply_settings()
end

View file

@ -0,0 +1,120 @@
local config = require("codecompanion.config")
local has_been_reasoning = false
local api = vim.api
---Add a message directly to the chat buffer. This will be visible to the user
---@param chat CodeCompanion.Chat
---@param data table
---@param opts? table
local function add_buf_message(chat, data, opts)
assert(type(data) == "table", "data must be a table")
if data.role == config.constants.SYSTEM_ROLE then
return
end
local lines = {}
local bufnr = chat.bufnr
local new_response = false
local function write(text)
for _, t in ipairs(vim.split(text, "\n", { plain = true, trimempty = false })) do
table.insert(lines, t)
end
end
-- Add a new header to the chat buffer
local function new_role()
new_response = true
chat.last_role = data.role
table.insert(lines, "")
table.insert(lines, "")
chat.ui:set_header(lines, config.strategies.chat.roles[data.role])
end
-- Add data to the chat buffer
local function append_data()
if data.reasoning then
if not has_been_reasoning then
table.insert(lines, "### Reasoning")
table.insert(lines, "")
end
has_been_reasoning = true
write(data.reasoning)
end
if data.content then
if has_been_reasoning then
has_been_reasoning = false
table.insert(lines, "")
table.insert(lines, "")
table.insert(lines, "### Response")
table.insert(lines, "")
end
write(data.content)
end
end
local function update_buffer()
chat.ui:unlock_buf()
local last_line, last_column, line_count = chat.ui:last()
if opts and opts.insert_at then
last_line = opts.insert_at
last_column = 0
end
local cursor_moved = api.nvim_win_get_cursor(0)[1] == line_count
api.nvim_buf_set_text(bufnr, last_line, last_column, last_line, last_column, lines)
if new_response then
chat.ui:render_headers()
end
if chat.last_role ~= config.constants.USER_ROLE then
chat.ui:lock_buf()
end
if config.display.chat.auto_scroll then
if cursor_moved and chat.ui:is_active() then
chat.ui:follow()
elseif not chat.ui:is_active() then
chat.ui:follow()
end
end
end
-- Handle a new role
if (data.role and data.role ~= chat.last_role) or (opts and opts.force_role) then
new_role()
end
-- Append the output from the LLM
if data.content or data.reasoning then
append_data()
update_buffer()
end
end
---Reset the chat buffer from messages
---@param chat CodeCompanion.Chat
---@param messages table[]
return function(chat, messages)
-- Clear current chat messages
chat.messages = {}
-- Restore messages exactly as they were dumped
chat.messages = vim.deepcopy(messages)
-- cycle <- the cycle of latest message
chat.cycle = #messages > 0 and messages[#messages].cycle + 1 or 1
vim.api.nvim_buf_set_lines(chat.bufnr, 3, -1, false, {})
add_buf_message(chat, { role = config.constants.USER_ROLE, content = "" })
for _, message in ipairs(messages) do
add_buf_message(chat, message)
end
add_buf_message(chat, { role = config.constants.USER_ROLE, content = "" })
chat:set_range(-2)
chat.status = config.constants.SUCCESS_STATUS
end

View file

@ -0,0 +1,5 @@
return {
-- require("plugins.ai.codecompanion"),
require("plugins.ai.avante"),
require("plugins.ai.mchub"),
}

View file

@ -0,0 +1,14 @@
return {
{
"ravitemer/mcphub.nvim",
-- from nix
dev = true,
dependencies = {
"nvim-lua/plenary.nvim", -- Required for Job and HTTP requests
},
cmd = "MCPHub", -- lazy load by default
config = function()
require("mcphub").setup()
end,
},
}

View file

@ -0,0 +1,202 @@
local vectorcode_cacher = nil
local has_vc = nil
local vectorcacher = function()
if has_vc ~= nil then
return has_vc, vectorcode_cacher
end
local vectorcode_config
has_vc, vectorcode_config = pcall(require, "vectorcode.config")
if has_vc then
vectorcode_cacher = vectorcode_config.get_cacher_backend()
end
return has_vc, vectorcode_cacher
end
-- roughly equate to 2000 tokens for LLM
local RAG_Context_Window_Size = 8000
local get_prompt = function(get_prompt_message, file_sep, fim_suf, fim_pref, fim_mid)
get_prompt_message = get_prompt_message or function()
return ""
end
return function(pref, suff)
local prompt_message = get_prompt_message()
local h_vc, vc = vectorcacher()
if h_vc and vc then
for _, file in ipairs(vc.query_from_cache(0)) do
prompt_message = file_sep .. file.path .. "\n" .. file.document
end
end
prompt_message = vim.fn.strcharpart(prompt_message, 0, RAG_Context_Window_Size)
local msg = prompt_message .. fim_suf .. suff .. fim_pref .. pref .. fim_mid
return msg
end
end
local AiRun = {
api_key = "AI_RUN_TOKEN",
name = "AiRun",
stream = true,
end_point = vim.g.airun_endpoint,
model = vim.g.airun_model,
template = {
prompt = get_prompt(nil, "<[file-sep]>", "<[fim-suffix]>", "<[fim-prefix]>", "<[fim-middle]>"),
suffix = false,
},
optional = {
stop = {
"<|endoftext|>",
"<|fim-prefix|>",
"<|fim-middle|>",
"<|fim-suffix|>",
"<|fim-pad|>",
"<|repo_name|>",
"<|file-sep|>",
},
max_tokens = 300,
},
}
local QwenCoder = {
api_key = "TERM",
name = "OPENCODER",
stream = true,
end_point = vim.g.ollama_completions_endpoint,
model = "qwen2.5-coder:3b-instruct-q8_0",
template = {
prompt = get_prompt(nil, "<[file_sep]>", "<[fim_suffix]>", "<[fim_prefix]>", "<[fim_middle]>"),
suffix = false,
},
optional = {
max_tokens = 300,
},
}
local attach = function(bufnr)
local lsps = vim.lsp.get_clients({ name = "minuet", bufnr = bufnr })
if #lsps and #lsps > 0 then
vim.notify("Minuet LSP already attached to current buffer", vim.log.levels.INFO)
return
end
require("minuet.lsp").start_server({ buf = bufnr })
end
local detach = function(bufnr)
local lsps = vim.lsp.get_clients({ name = "minuet", bufnr = bufnr })
if #lsps == 0 then
vim.notify("Minuet LSP not attached to current buffer", vim.log.levels.INFO)
return
end
for _, client in ipairs(lsps) do
vim.lsp.buf_detach_client(bufnr, client.id)
end
vim.notify("Minuet LSP detached from current buffer", vim.log.levels.INFO)
end
local enable_auto_trigger = function(bufnr)
local lsps = vim.lsp.get_clients({ name = "minuet", bufnr = bufnr })
if #lsps == 0 then
vim.b[bufnr].minuet_lsp_enable_auto_trigger = true
attach()
return
end
for _, client in ipairs(lsps) do
vim.lsp.completion.enable(true, client.id, bufnr, { autotrigger = true })
end
vim.notify("Minuet LSP is enabled for auto triggering", vim.log.levels.INFO)
end
local disable_auto_trigger = function(bufnr)
vim.b[bufnr].minuet_lsp_enable_auto_trigger = nil
local lsps = vim.lsp.get_clients({ name = "minuet", bufnr = bufnr })
if #lsps == 0 then
return
end
for _, client in ipairs(lsps) do
vim.lsp.completion.enable(false, client.id, bufnr)
vim.notify("Minuet LSP is disabled for auto triggering", vim.log.levels.INFO)
end
end
return {
{
"milanglacier/minuet-ai.nvim",
cmd = { "Minuet" },
-- keys = {
-- {
-- "<C-x><C-z>",
-- function()
-- local bufnr = vim.api.nvim_get_current_buf()
-- attach(bufnr)
-- enable_auto_trigger(bufnr)
-- vim.api.nvim_create_autocmd({ "InsertLeave", "BufLeave", "BufWinLeave" }, {
-- once = true,
-- callback = function()
-- if vim.b[bufnr].minuet_lsp_enable_auto_trigger then
-- disable_auto_trigger(bufnr)
-- detach(bufnr)
-- end
-- end,
-- })
-- end,
-- mode = "i",
-- },
-- },
config = function()
-- This uses the async cache to accelerate the prompt construction.
-- There's also the require('vectorcode').query API, which provides
-- more up-to-date information, but at the cost of blocking the main UI.
require("minuet").setup({
add_single_line_entry = true,
n_completions = 2,
-- I recommend you start with a small context window firstly, and gradually
-- increase it based on your local computing power.
context_window = 4096,
after_cursor_filter_length = 30,
debounce = 600,
-- notify = "debug",
provider = "openai_fim_compatible",
provider_options = {
openai_fim_compatible = AiRun,
-- openai_fim_compatible = QwenCoder,
},
request_timeout = 10,
-- virtualtext = {
-- auto_trigger_ft = {},
-- keymap = {
-- -- accept whole completion
-- accept = '<A-a>',
-- -- accept one line
-- accept_line = '<A-a>',
-- -- accept n lines (prompts for number)
-- -- e.g. "A-z 2 CR" will accept 2 lines
-- accept_n_lines = '<A-z>',
-- -- Cycle to prev completion item, or manually invoke completion
-- prev = '<A-[>',
-- -- Cycle to next completion item, or manually invoke completion
-- next = '<A-]>',
-- dismiss = '<A-e>',
-- },
-- },
-- lsp = {
-- enabled_ft = { "lua", "python" },
-- },
})
end,
},
}

View file

@ -0,0 +1,4 @@
return {
require("plugins.autocomplete.ai"),
require("plugins.autocomplete.blink"),
}

View file

@ -0,0 +1,80 @@
if vim.g.modern_ui then
return {
{
"aileot/ex-colors.nvim",
lazy = true,
cmd = "ExColors",
---@type ExColors.Config
config = function()
require("ex-colors").setup({
required_syntaxes = {
"diff", -- "diffAdded", "diffRemoved", "diffChanged"
"html",
"markdown",
},
included_patterns = require("ex-colors.presets").recommended.included_patterns + {
"BlinkCmp",
"GitSigns",
"RainbowDelimiter",
"MiniStatusline",
},
})
end,
},
{
"ribru17/bamboo.nvim",
enabled = false,
lazy = false,
priority = math.huge,
config = function()
require("bamboo").setup({
code_style = {
comments = { italic = true },
conditionals = { italic = true },
keywords = { bold = true },
functions = { bold = true },
namespaces = { italic = true },
parameters = { italic = true },
strings = {},
variables = {},
},
dim_inactive = true,
-- style = "multiplex",
transparent = false,
lualine = {
transparent = true, -- lualine center bar transparency
},
diagnostics = {
darker = true, -- darker colors for diagnostic
undercurl = true, -- use undercurl instead of underline for diagnostics
background = true, -- use background color for virtual text
},
})
require("bamboo").load()
vim.opt.background = "light"
vim.api.nvim_command("colorscheme bamboo-light")
end,
},
{
"uloco/bluloco.nvim",
enabled = true,
lazy = false,
priority = math.huge,
dependencies = { "rktjmp/lush.nvim" },
config = function()
require("bluloco").setup({
style = "auto", -- "auto" | "dark" | "light"
transparent = false,
italics = true,
terminal = vim.fn.has("gui_running") == 1, -- bluoco colors are enabled in gui terminals per default.
guicursor = true,
rainbow_headings = true, -- if you want different colored headings for each heading level
})
vim.api.nvim_command("colorscheme bluloco")
end,
},
}
else
vim.api.nvim_command("colorscheme default")
return {}
end

View file

@ -0,0 +1,61 @@
local is_large_file = require("largefiles").is_large_file
vim.g.skip_ts_context_commentstring_module = true
return {
{
"numToStr/Comment.nvim",
config = function()
require("Comment").setup({
-- pre_hook = require("ts_context_commentstring.integrations.comment_nvim").create_pre_hook(),
ignore = function()
return is_large_file(vim.api.nvim_get_current_buf(), true)
end,
mappings = {
---Operator-pending mapping; `gcc` `gbc` `gc[count]{motion}` `gb[count]{motion}`
basic = false,
---Extra mapping; `gco`, `gcO`, `gcA`
extra = false,
},
})
end,
keys = {
{
"gcc",
function()
local vvar = vim.api.nvim_get_vvar
return vvar("count") == 0 and "<Plug>(comment_toggle_linewise_current)"
or "<Plug>(comment_toggle_linewise_count)"
end,
expr = true,
desc = "Comment toggle current line",
},
{
"gbc",
function()
local vvar = vim.api.nvim_get_vvar
return vvar("count") == 0 and "<Plug>(comment_toggle_blockwise_current)"
or "<Plug>(comment_toggle_blockwise_count)"
end,
expr = true,
desc = "Comment toggle current block",
},
{ "gc", "<Plug>(comment_toggle_linewise)", desc = "Comment toggle linewise" },
{ "gb", "<Plug>(comment_toggle_blockwise)", desc = "Comment toggle linewise" },
{
"gc",
"<Plug>(comment_toggle_linewise_visual)",
mode = { "x" },
desc = "Comment toggle linewise (visual)",
},
{
"gb",
"<Plug>(comment_toggle_blockwise_visual)",
mode = { "x" },
desc = "Comment toggle blockwise (visual)",
},
},
},
}

View file

@ -0,0 +1,147 @@
local M = {
neofetch = "",
version = "",
plugins = "",
}
local function draw_footer(dashboard)
local footer = {
M.version,
M.plugins,
}
if type(M.neofetch) ~= "string" then
table.insert(
footer,
string.format("%s\t%s", M.neofetch[1]["result"]["prettyName"], M.neofetch[2]["result"]["release"])
)
local uptime = M.neofetch[3]["result"]["uptime"] / 1000
local h = uptime / 3600
local m = 60 - (math.ceil(h) - h) * 60
local s = 60 - math.floor((math.ceil(m) - m) * 60)
m = math.floor(m)
h = math.floor(h)
table.insert(footer, string.format("uptime: %sh %sm %ss", h, m, s))
end
dashboard.section.footer.val = footer
vim.cmd.AlphaRedraw()
end
local function fetch(dashboard)
local neofetch = vim.fn.executable("fastfetch")
if neofetch == 0 then
return
end
local cmd = "fastfetch"
local args = { "--structure", "OS:Kernel:Uptime", "--format", "json" }
local t = ""
local stdout = function(error, data)
if data then
t = t .. data
end
end
local on_exit = function(...)
if #t > 0 then
M.neofetch = vim.json.decode(t)
end
local timer = vim.uv.new_timer()
timer:start(
20,
0,
vim.schedule_wrap(function()
draw_footer(dashboard)
end)
)
end
vim.system({ cmd, table.unpack(args) }, {
text = true,
stdout = stdout,
}, on_exit)
end
return {
"goolord/alpha-nvim",
cond = function()
-- nix 8..
if #vim.v.argv > 8 then
return false
end
return not vim.env.YAZI_ID
end,
config = function()
local height = tonumber(vim.api.nvim_command_output("echo &lines")) or 0
local dashboard = require("alpha.themes.dashboard")
dashboard.autostart = true
dashboard.config.layout[1].val = 1
dashboard.section.buttons.val = {
dashboard.button("n", "" .. " New file", ":ene <BAR> startinsert <CR>"),
dashboard.button("f", "" .. " Find file", ":FzfLua files<cr>"),
dashboard.button("a", "󰊳 " .. " AI", function()
local buf = vim.api.nvim_get_current_buf()
vim.cmd([[:CodeCompanionChat]])
vim.cmd("bd " .. tostring(buf))
end),
dashboard.button("s", "" .. " Search", ":FzfLua grep_project<cr>"),
dashboard.button(
"r",
"󰄉 " .. " Recent files",
":lua require('fzf-lua').oldfiles({ multiprocess = true, cwd_only=true })<cr>"
),
dashboard.button("g", "󰄉 " .. " Diff", ":DiffviewOpen <cr>"),
dashboard.button("c", "" .. " Config", ":e .nvim.lua <CR>"),
dashboard.button("u", "󰊳 " .. " Update Plugins", ":Lazy update<CR>"),
dashboard.button("q", "" .. " Quit", ":qa<CR>"),
}
-- set highlight
for _, button in ipairs(dashboard.section.buttons.val) do
button.opts.hl = "AlphaButtons"
button.opts.hl_shortcut = "AlphaShortcut"
end
dashboard.section.header.opts.hl = "AlphaHeader"
dashboard.section.buttons.opts.hl = "AlphaButtons"
dashboard.section.footer.opts.hl = "AlphaFooter"
if height > 40 then
local header = require("banner").get_by_day()
dashboard.section.header.val = header
fetch(dashboard)
else
dashboard.section.header.val = ""
end
-- close Lazy and re-open when the dashboard is ready
local ft = vim.filetype.match({ buf = 0 })
if ft == "lazy" then
vim.cmd.close()
vim.api.nvim_create_autocmd("User", {
pattern = "AlphaReady",
callback = function()
require("lazy").show()
end,
})
end
require("alpha").setup(dashboard.opts)
vim.api.nvim_create_autocmd("User", {
pattern = "LazyVimStarted",
callback = function()
local stats = require("lazy").stats()
local ms = (math.floor(stats.startuptime * 100 + 0.5) / 100)
M.version = string.format("󰥱 v%s", vim.version())
M.plugins = "⚡Neovim loaded " .. stats.loaded .. "/" .. stats.count .. " plugins in " .. ms .. "ms"
if height > 60 then
draw_footer(dashboard)
end
end,
})
end,
dependencies = {
-- { "JMarkin/ascii.nvim", lazy = true },
},
}

46
nvim/lua/plugins/db.lua Normal file
View file

@ -0,0 +1,46 @@
local is_not_mini = require("funcs").is_not_mini
local autocmd = vim.api.nvim_create_autocmd
return {
{
"tpope/vim-dadbod",
-- from nix
dev = true,
lazy = true,
ft = { "sql", "mssql", "plsql" },
},
{
"kristijanhusak/vim-dadbod-completion",
-- from nix
dev = true,
lazy = true,
ft = { "sql", "mssql", "plsql" },
},
{
"kristijanhusak/vim-dadbod-ui",
-- from nix
dev = true,
cond = is_not_mini,
dependencies = {
"tpope/vim-dadbod",
"kristijanhusak/vim-dadbod-completion",
},
init = function(event)
vim.g.db_ui_execute_on_save = 0
vim.g.db_ui_win_position = "right"
vim.g.db_ui_show_database_icon = 1
vim.g.db_ui_use_nerd_fonts = 1
vim.g.db_ui_env_variable_url = "DATABASE_URL"
vim.g.db_ui_use_nvim_notify = true
vim.g.db_ui_auto_execute_table_helpers = 1
autocmd("FileType", {
pattern = { "dbui" },
callback = function()
vim.keymap.set("n", "<tab>", "<Plug>(DBUI_SelectLine)", { buffer = event.buffer, silent = true })
end,
})
end,
cmd = { "DBUI", "DBUIToggle" },
},
}

288
nvim/lua/plugins/debug.lua Normal file
View file

@ -0,0 +1,288 @@
local is_not_mini = require("funcs").is_not_mini
local python_attach = function(options)
local dap = require("dap")
options = {
host = options.host or "0.0.0.0",
port = options.port or 5678,
remote_root = options.remote_root or "/app",
}
local host = options.host -- This should be configured for remote debugging if your SSH tunnel is setup.
-- You can even make nvim responsible for starting the debugpy server/adapter:
-- vim.fn.system({"${some_script_that_starts_debugpy_in_your_container}", ${script_args}})
local pythonAttachAdapter = {
type = "server",
host = host,
port = options.port,
}
local pythonAttachConfig = {
type = "python",
request = "attach",
connect = {
port = options.port,
host = host,
},
mode = "remote",
name = "Remote Attached Debugger",
cwd = vim.fn.getcwd(),
pathMappings = {
{
localRoot = vim.fn.getcwd(), -- Wherever your Python code lives locally.
remoteRoot = options.remote_root, -- Wherever your Python code lives in the container.
},
},
}
local session = dap.attach(pythonAttachAdapter, pythonAttachConfig)
if session == nil then
io.write("Error launching adapter")
end
require("dapui").open()
end
vim.api.nvim_create_user_command("PythonRemoteAttach", function(opts)
python_attach({ remote_root = opts.fargs[1] or vim.fn.getcwd() })
end, {
nargs = "*",
complete = "file_in_path",
})
return {
"rcarriga/nvim-dap-ui",
cond = is_not_mini,
lazy = true,
dependencies = {
{
"mfussenegger/nvim-dap",
},
{
"theHamsta/nvim-dap-virtual-text",
opts = {},
dependencies = "nvim-treesitter",
},
"ofirgall/goto-breakpoints.nvim",
{
"LiadOz/nvim-dap-repl-highlights",
dependencies = "nvim-treesitter",
},
"mfussenegger/nvim-dap-python",
"leoluz/nvim-dap-go",
},
config = function()
local dap, dapui = require("dap"), require("dapui")
require("dap-python").setup(require("utils.python_venv").getPythonEnv())
require("dap-go").setup()
dapui.setup({
mappings = {
-- Use a table to apply multiple mappings
expand = { "<CR>", "<2-LeftMouse>", "za" },
},
controls = {
enabled = vim.fn.exists("+winbar") == 1,
element = "repl",
icons = {
pause = "",
play = "(F5)",
step_into = "(F11)",
step_over = "(F10)",
step_out = "(F12)",
step_back = "(F9)",
run_last = "(<leader>dl)",
terminate = "",
disconnect = "",
},
},
layouts = {
{
-- You can change the order of elements in the sidebar
elements = {
-- Provide IDs as strings or tables with "id" and "size" keys
{ id = "breakpoints", size = 0.1 },
{ id = "watches", size = 0.1 },
{
id = "scopes",
size = 0.45, -- Can be float or integer > 1
},
{ id = "stacks", size = 0.25 },
},
size = 40,
position = "left", -- Can be "left" or "right"
},
{
elements = {
"repl",
"console",
},
size = 10,
position = "bottom", -- Can be "bottom" or "top"
},
},
})
dap.listeners.after.event_initialized["dapui_config"] = function()
dapui.open()
end
dap.listeners.before.event_terminated["dapui_config"] = function()
dapui.close()
end
dap.listeners.before.event_exited["dapui_config"] = function()
dapui.close()
end
require("nvim-dap-repl-highlights").setup()
end,
keys = {
{
"<leader>dc",
function()
require("dapui").close()
end,
desc = "Dap: UIClose",
},
{
"<leader>do",
function()
require("dapui").open()
end,
desc = "Dap: UIOpen",
},
{
"<leader>dd",
function()
require("dapui").toggle()
end,
desc = "Dap: UIToggle",
},
{
"<F5>",
function()
require("dap").continue()
end,
desc = "Dap: continue",
},
{
"<F10>",
function()
require("dap").step_over()
end,
desc = "Dap: step over",
},
{
"<F11>",
function()
require("dap").step_into()
end,
desc = "Dap: step into",
},
{
"<F12>",
function()
require("dap").step_out()
end,
desc = "Dap: step out",
},
{
"<F9>",
function()
require("dap").step_back()
end,
desc = "Dap: step back",
},
{
"<leader>db",
function()
require("dap").toggle_breakpoint()
end,
desc = "Dap: ToggleBreakpoint",
},
{
"<leader>dB",
function()
require("dap").set_breakpoint()
end,
desc = "Dap: SetBreakpoint",
},
{
"<leader>dr",
function()
require("dap").repl.open()
end,
desc = "Dap: Repl",
},
{
"<leader>dl",
function()
require("dap").run_last()
end,
desc = "Dap: run last",
},
{
"<leader>dh",
function()
require("dap.ui.widgets").hover()
end,
desc = "Dap: Hover",
mode = { "n", "v" },
},
{
"<leader>dp",
function()
require("dap.ui.widgets").preview()
end,
desc = "Dap: Preview",
mode = { "n", "v" },
},
{
"<leader>df",
function()
local widgets = require("dap.ui.widgets")
widgets.centered_float(widgets.frames)
end,
desc = "Dap: Frames",
},
{
"<leader>ds",
function()
local widgets = require("dap.ui.widgets")
widgets.centered_float(widgets.scopes)
end,
desc = "Dap: Scopes",
},
{
"<leader>de",
function(...)
require("dapui").float_element(...)
end,
desc = "Dap: UIFloatElement",
mode = "v",
},
{
"<leader>dE",
function(...)
require("dapui").eval(...)
end,
desc = "Dap: Eval",
mode = "v",
},
{
"]D",
function()
require("goto-breakpoints").next()
end,
desc = "Next breakkpoint",
},
{
"[D",
function()
require("goto-breakpoints").prev()
end,
desc = "Prev breakkpoint",
},
{
"]S",
function()
require("goto-breakpoints").stopped()
end,
},
},
cmd = { "PythonRemoteAttach" },
}

31
nvim/lua/plugins/dev.lua Normal file
View file

@ -0,0 +1,31 @@
-- for developments
return {
{
"stevearc/profile.nvim",
cond = function()
return os.getenv("NVIM_PROFILE")
end,
lazy = true,
config = function()
vim.keymap.set("", "<F2>", function()
local prof = require("profile")
if prof.is_recording() then
prof.stop()
vim.ui.input(
{ prompt = "Save profile to:", completion = "file", default = "profile.json.log" },
function(filename)
if filename then
prof.export(filename)
vim.cmd([[profile stop]])
vim.notify(string.format("Wrote %s", filename))
end
end
)
else
prof.start("*")
end
end)
end,
},
}

View file

@ -0,0 +1,24 @@
return {
"JMarkin/diaglist.nvim",
-- dev = true,
-- enabled = false,
opts = {
debounce_ms = 130,
},
keys = {
{
"<space>E",
function()
require("diaglist").open_all_diagnostics()
end,
desc = "All Diagnostics",
},
{
"<space>e",
function()
require("diaglist").open_buffer_diagnostics()
end,
desc = "Buffer Diagnostics",
},
},
}

View file

@ -0,0 +1 @@
return

View file

@ -0,0 +1,19 @@
return {
"junegunn/vim-easy-align",
keys = {
{ "gl", "<Plug>(EasyAlign)", mode = { "v", "x" }, noremap = false, desc = "EazyAlign" },
{ "gL", "<Plug>(LiveEasyAlign)", mode = { "v", "x" }, noremap = false, desc = "EazyAlign Live" },
},
init = function()
vim.g.easy_align_delimiters = {
["\\"] = {
pattern = [[\\\+]],
},
["/"] = {
pattern = [[//\+\|/\*\|\*/]],
delimiter_align = "c",
ignore_groups = "!Comment",
},
}
end,
}

View file

@ -0,0 +1,110 @@
vim.keymap.set("n", "<space>f", "<cmd>Oil<cr>", { noremap = true, desc = "Netrw: open" })
local detail = false
-- Declare a global function to retrieve the current directory
function _G.get_oil_winbar()
local bufnr = vim.api.nvim_win_get_buf(vim.g.statusline_winid)
local dir = require("oil").get_current_dir(bufnr)
if dir then
return vim.fn.fnamemodify(dir, ":~")
else
-- If there is no current directory (e.g. over ssh), just show the buffer name
return vim.api.nvim_buf_get_name(0)
end
end
vim.api.nvim_create_autocmd("User", {
pattern = "OilActionsPost",
callback = function(event)
if event.data.actions.type == "move" then
Snacks.rename.on_rename_file(event.data.actions.src_url, event.data.actions.dest_url)
end
end,
})
return {
{
"stevearc/oil.nvim",
---@module 'oil'
---@type oil.SetupOpts
opts = {
win_options = {
winbar = "%!v:lua.get_oil_winbar()",
},
watch_for_changes = true,
use_default_keymaps = false,
keymaps = {
["g?"] = { "actions.show_help", mode = "n" },
["q"] = {
desc = "close and restore prev buffer",
callback = function()
require("oil").close()
end,
},
["<CR>"] = "actions.select",
["<C-v>"] = { "actions.select", opts = { vertical = true } },
["<C-s>"] = { "actions.select", opts = { horizontal = true } },
["<C-t>"] = { "actions.select", opts = { tab = true } },
["<C-p>"] = "actions.preview",
["<C-c>"] = { "actions.close", mode = "n" },
["<C-r>"] = "actions.refresh",
["-"] = { "actions.parent", mode = "n" },
["_"] = { "actions.open_cwd", mode = "n" },
["<tab>"] = "actions.select",
["<s-tab>"] = { "actions.parent", mode = "n" },
["~"] = { "actions.cd", opts = { scope = "tab" }, mode = "n" },
["s"] = { "actions.change_sort", mode = "n" },
["gh"] = { "actions.toggle_hidden", mode = "n" },
["gd"] = {
desc = "Toggle file detail view",
callback = function()
detail = not detail
if detail then
require("oil").set_columns({ "icon", "permissions", "size", "mtime" })
else
require("oil").set_columns({ "icon" })
end
end,
},
},
preview_win = {
-- A function that returns true to disable preview on a file e.g. to avoid lag
disable_preview = function(filename)
local funcs = require("funcs")
local path = filename
if not funcs.is_text(path) then
return true
end
-- if file > 5 MB or not text -> not preview
local size = funcs.get_size(path)
if type(size) ~= "number" then
return true
end
if size > 5 then
return true
end
-- len
local len = funcs.maxline(path)
if type(len) ~= "number" then
return true
end
if len > vim.o.synmaxcol then
return true
end
return false
end,
-- Window-local options to use for preview window buffers
win_options = {},
},
},
-- Optional dependencies
dependencies = { "echasnovski/mini.icons" },
lazy = false,
},
}

368
nvim/lua/plugins/fzflua.lua Normal file
View file

@ -0,0 +1,368 @@
local autocmd = vim.api.nvim_create_autocmd
local augroup = vim.api.nvim_create_augroup
return {
"ibhagwan/fzf-lua",
cmd = "FzfLua",
lazy = true,
keys = {
{
"<leader>sq",
function()
require("fzf-lua").quickfix({ multiprocess = true })
end,
desc = "Search: quickfix",
},
{
"<leader>sr",
function()
require("fzf-lua").oldfiles({
multiprocess = true,
cwd_only = true,
})
end,
desc = "Search: old files",
},
{
"<leader>sl",
function()
require("fzf-lua").loclist({ multiprocess = true })
end,
desc = "Search: loclist",
},
{
"<leader>ss",
function()
require("fzf-lua").resume({ multiprocess = true })
end,
desc = "Search: previous",
},
{
"<leader>sb",
function()
require("fzf-lua").buffers({ multiprocess = true, current_tab_only = true })
end,
desc = "Search: buffers",
},
{
"<leader>sf",
function()
require("fzf-lua").files({ multiprocess = true })
end,
desc = "Search: find files",
},
{
"<leader>sg",
function()
require("fzf-lua").grep_project({ multiprocess = true })
end,
desc = "Search: project",
},
{
"<leader>sg",
function()
require("fzf-lua").grep_visual({ multiprocess = true })
end,
desc = "Search: project",
mode = "v",
},
{
"grc",
function()
require("fzf-lua").grep_cword({ multiprocess = true })
end,
desc = "Search: references",
},
{
"grc",
function()
require("fzf-lua").grep_visual({ multiprocess = true })
end,
desc = "Search: visual references",
mode = "v",
},
{
"<leader>s/",
function()
require("fzf-lua").lgrep_curbuf({ multiprocess = true })
end,
desc = "Search: current buffer",
},
{
"<leader>st",
function()
require("fzf-lua").btags({ multiprocess = true, cwd = vim.uv.cwd() })
end,
desc = "Search: tags current file",
},
{
"<leader>sT",
function()
require("fzf-lua").tags({ multiprocess = true, cwd = vim.uv.cwd() })
end,
desc = "Search: tags global",
},
{
"<leader>sT",
function()
require("fzf-lua").tags_grep_visual({ multiprocess = true, cwd = vim.uv.cwd() })
end,
desc = "Search: tags",
mode = "v",
},
{
"<leader>sh",
function()
require("fzf-lua").help_tags({ multiprocess = true })
end,
desc = "Search: helptags",
},
{
"<leader>sc",
function()
require("fzf-lua").commands({ multiprocess = true })
end,
desc = "Search: commands",
},
{
"<leader>sk",
function()
require("fzf-lua").keymaps({ multiprocess = true })
end,
desc = "Search: keymaps",
},
{
"<leader>sch",
function()
require("fzf-lua").command_history({ multiprocess = true })
end,
desc = "Search: command_history",
},
{
"<leader>gt",
function()
require("fzf-lua").git_status({ multiprocess = true })
end,
desc = "Search: git status",
},
{
"<leader>gC",
function()
require("fzf-lua").git_commits({ multiprocess = true })
end,
desc = "Search: git commits",
},
{
"<leader>gc",
function()
require("fzf-lua").git_bcommits({ multiprocess = true })
end,
desc = "Search: git commits",
},
},
config = function()
local actions = require("fzf-lua.actions")
require("fzf-lua").setup({
-- fzf_bin = "sk",
async_or_timeout = 3000,
global_resume = false,
global_resume_query = false,
winopts = {
preview = { default = "builtin" },
on_create = function()
vim.b.term_ignore = true
vim.keymap.set("t", "<C-n>", "<Down>", { silent = true, buffer = true })
vim.keymap.set("t", "<C-p>", "<Up>", { silent = true, buffer = true })
end,
},
previewers = {
builtin = {
syntax = true, -- preview syntax highlight?
treesitter = { enabled = true, disabled = {} },
},
},
keymap = {
builtin = {
["<F1>"] = "toggle-help",
["<F2>"] = "toggle-fullscreen",
["<F3>"] = "toggle-preview-wrap",
["<F4>"] = "toggle-preview",
["<F5>"] = "toggle-preview-ccw",
["<F6>"] = "toggle-preview-cw",
["<C-d>"] = "preview-page-down",
["<C-e>"] = "preview-page-up",
["<C-r>"] = "preview-page-reset",
},
fzf = {
["ctrl-z"] = "abort",
["ctrl-u"] = "unix-line-discard",
["ctrl-f"] = "half-page-down",
["ctrl-b"] = "half-page-up",
["ctrl-a"] = "beginning-of-line",
["alt-a"] = "toggle-all",
["f3"] = "toggle-preview-wrap",
["f4"] = "toggle-preview",
["ctrl-d"] = "preview-page-down",
["ctrl-e"] = "preview-page-up",
["tab"] = "down",
["shift-tab"] = "up",
["ctrl-space"] = "toggle+down",
},
},
files = {
fd_opts = [[--color=never --hidden --type f --type l --exclude .git --strip-cwd-prefix ]],
-- fd_opts = [[--color=never --hidden --type f --type l --exclude .git ]],
actions = {
["ctrl-g"] = { actions.toggle_ignore },
["tab"] = false,
["enter"] = actions.file_edit_or_qf,
["ctrl-s"] = actions.file_split,
["ctrl-v"] = actions.file_vsplit,
["ctrl-t"] = actions.file_tabedit,
["alt-q"] = actions.file_sel_to_qf,
["alt-Q"] = actions.file_sel_to_ll,
["alt-i"] = actions.toggle_ignore,
["alt-h"] = actions.toggle_hidden,
["alt-f"] = actions.toggle_follow,
},
},
fzf_opts = {
["--ansi"] = "",
-- ["--info"] = "inline",
-- ["--height"] = "100%",
-- ["--layout"] = "reverse",
-- ["--border"] = "none",
},
lsp = {
code_actions = {
previewer = "codeaction_native",
preview_pager = [[delta --side-by-side --width=$COLUMNS --hunk-header-style="omit" --file-style="omit"]],
},
},
helptags = {
actions = {
-- Open help pages in a vertical split.
["default"] = actions.help_vert,
},
},
oldfiles = {
include_current_session = true,
fzf_opts = { ["--tiebreak"] = "index" },
},
grep = {
rg_opts = "--multiline --column --line-number --no-heading --color=always --smart-case --max-columns=4096 -e",
},
git = {
files = {
prompt = "GitFiles ",
cmd = "git ls-files --exclude-standard",
multiprocess = true, -- run command in a separate process
-- force display the cwd header line regardles of your current working
-- directory can also be used to hide the header when not wanted
-- cwd_header = true
},
status = {
prompt = "GitStatus ",
cmd = "git -c color.status=false status -su",
previewer = "git_diff",
-- uncomment if you wish to use git-delta as pager
preview_pager = "delta --width=${FZF_PREVIEW_COLUMNS}",
actions = {
-- actions inherit from 'actions.files' and merge
["right"] = { fn = actions.git_unstage, reload = true },
["left"] = { fn = actions.git_stage, reload = true },
["ctrl-x"] = { fn = actions.git_reset, reload = true },
},
-- If you wish to use a single stage|unstage toggle instead
-- using 'ctrl-s' modify the 'actions' table as shown below
-- actions = {
-- ["right"] = false,
-- ["left"] = false,
-- ["ctrl-x"] = { fn = actions.git_reset, reload = true },
-- ["ctrl-s"] = { fn = actions.git_stage_unstage, reload = true },
-- },
},
commits = {
prompt = "Commits ",
cmd = "git log --color --pretty=format:'%C(yellow)%h%Creset %Cgreen(%><(12)%cr%><|(12))%Creset %s %C(blue)<%an>%Creset'",
preview = "git show --pretty='%Cred%H%n%Cblue%an <%ae>%n%C(yellow)%cD%n%Cgreen%s' --color {1}",
-- uncomment if you wish to use git-delta as pager
preview_pager = "delta --width=${FZF_PREVIEW_COLUMNS}",
actions = {
["default"] = actions.git_checkout,
-- remove `exec_silent` or set to `false` to exit after yank
["ctrl-y"] = { fn = actions.git_yank_commit, exec_silent = true },
},
},
bcommits = {
prompt = "BCommits ",
-- default preview shows a git diff vs the previous commit
-- if you prefer to see the entire commit you can use:
-- git show --color {1} --rotate-to=<file>
-- {1} : commit SHA (fzf field index expression)
-- <file> : filepath placement within the commands
cmd = "git log --color --pretty=format:'%C(yellow)%h%Creset %Cgreen(%><(12)%cr%><|(12))%Creset %s %C(blue)<%an>%Creset' <file>",
preview = "git diff --color {1}^! -- <file>",
-- uncomment if you wish to use git-delta as pager
preview_pager = "delta --width=${FZF_PREVIEW_COLUMNS}",
actions = {
["default"] = actions.git_buf_edit,
["ctrl-s"] = actions.git_buf_split,
["ctrl-v"] = actions.git_buf_vsplit,
["ctrl-t"] = actions.git_buf_tabedit,
["ctrl-y"] = { fn = actions.git_yank_commit, exec_silent = true },
},
},
branches = {
prompt = "Branches ",
cmd = "git branch --all --color",
preview = "git log --graph --pretty=oneline --abbrev-commit --color {1}",
actions = {
["default"] = actions.git_switch,
},
},
tags = {
prompt = "Tags> ",
cmd = "git for-each-ref --color --sort=-taggerdate --format "
.. "'%(color:yellow)%(refname:short)%(color:reset) "
.. "%(color:green)(%(taggerdate:relative))%(color:reset)"
.. " %(subject) %(color:blue)%(taggername)%(color:reset)' refs/tags",
preview = "git log --graph --color --pretty=format:'%C(yellow)%h%Creset "
.. "%Cgreen(%><(12)%cr%><|(12))%Creset %s %C(blue)<%an>%Creset' {1}",
fzf_opts = { ["--no-multi"] = "" },
actions = { ["default"] = actions.git_checkout },
},
stash = {
prompt = "Stash> ",
cmd = "git --no-pager stash list",
preview = "git --no-pager stash show --patch --color {1}",
actions = {
["default"] = actions.git_stash_apply,
["ctrl-x"] = { fn = actions.git_stash_drop, reload = true },
},
fzf_opts = {
["--no-multi"] = "",
["--delimiter"] = "'[:]'",
},
},
},
})
require("fzf-lua").config.globals.fzf_opts["--border"] = nil
local fzf = "FZF"
augroup(fzf, { clear = true })
autocmd("VimResized", {
pattern = "*",
group = fzf,
command = 'lua require("fzf-lua").redraw()',
})
require("fzf-lua").register_ui_select()
end,
init = function()
vim.ui.select = function(...)
require("lazy").load({ plugins = { "fzf-lua" } })
return vim.ui.select(...)
end
end,
}

1
nvim/lua/plugins/git.lua Normal file
View file

@ -0,0 +1 @@
return

44
nvim/lua/plugins/http.lua Normal file
View file

@ -0,0 +1,44 @@
return {
{
{
"mistweaverco/kulala.nvim",
-- from nix
dev = true,
keys = {
{ "<leader>hr", desc = "Send request" },
{ "<leader>ha", desc = "Send all requests" },
{ "<leader>hb", desc = "Open scratchpad" },
},
ft = { "http", "rest" },
opts = {
-- your configuration comes here
global_keymaps = {
["Send request"] = { -- sets global mapping
"<leader>hr",
function()
require("kulala").run()
end,
mode = { "n", "v" }, -- optional mode, default is n
desc = "Send request", -- optional description, otherwise inferred from the key
},
["Send all requests"] = {
"<leader>ha",
function()
require("kulala").run_all()
end,
mode = { "n", "v" },
ft = "http", -- sets mapping for *.http files only
},
["Replay the last request"] = {
"<leader>hl",
function()
require("kulala").replay()
end,
ft = { "http", "rest" }, -- sets mapping for specified file types
},
["Find request"] = false, -- set to false to disable
},
},
},
},
}

136
nvim/lua/plugins/joins.lua Normal file
View file

@ -0,0 +1,136 @@
local function get_pos_lang(node)
local c = vim.api.nvim_win_get_cursor(0)
local range = { c[1] - 1, c[2], c[1] - 1, c[2] }
local buf = vim.api.nvim_get_current_buf()
local ok, parser = pcall(vim.treesitter.get_parser, buf, vim.treesitter.language.get_lang(vim.bo[buf].ft))
if not ok then
return ""
end
local current_tree = parser:language_for_range(range)
return current_tree:lang()
end
return {
{ "echasnovski/mini.splitjoin", lazy = true },
{
"Wansmer/treesj",
keys = {
{
"gS",
":lua require('treesj').join()<cr>",
desc = "join lines",
silent = true,
},
{
"gs",
":lua require('treesj').split()<cr>",
desc = "split lines",
silent = true,
},
{
"gm",
function()
local tsj_langs = require("treesj.langs")["presets"]
local lang = get_pos_lang()
if lang ~= "" and tsj_langs[lang] then
require("treesj").toggle()
else
require("mini.splitjoin").toggle()
end
end,
desc = "Toggle single/multiline by current position",
silent = true,
},
{
"gM",
function()
require("treesj").toggle({ split = { recursive = true }, join = { recursive = true } })
end,
desc = "Toggle single/multiline block of code",
},
},
dependencies = { "nvim-treesitter/nvim-treesitter" }, -- if you install parsers with `nvim-treesitter`
config = function()
local langs = require("treesj.langs").presets
local lu = require("treesj.langs.utils")
for _, nodes in pairs(langs) do
nodes.comment = {
both = {
fallback = function(_)
local res = require("mini.splitjoin").toggle()
if not res then
vim.cmd("normal! gww")
end
end,
},
}
end
local classnames = {
both = {
---@param tsn TSNode
enable = function(tsn)
local parent = tsn:parent()
if not parent or parent:type() ~= "jsx_attribute" then
return false
end
---@diagnostic disable-next-line: param-type-mismatch (jsx_attribute with no children does not exist.)
local attr_name = vim.treesitter.get_node_text(parent:child(0), 0)
return attr_name == "className"
end,
},
split = {
format_tree = function(tsj)
local str = tsj:child("string_fragment")
local words = vim.split(str:text(), " ")
tsj:remove_child("string_fragment")
for i, word in ipairs(words) do
tsj:create_child({ text = word }, i + 1)
end
end,
},
}
local parenthesized_expression = lu.set_preset_for_args()
require("treesj").setup({
max_join_length = 10000,
use_default_keymaps = false,
langs = {
tsx = {
["string"] = classnames,
interface_declaration = { target_nodes = { "object_type" } },
parenthesized_expression = parenthesized_expression,
jsx_expression = lu.set_default_preset(),
return_statement = {
target_nodes = {
["jsx_element"] = "root_jsx_element",
"jsx_self_closing_element",
"parenthesized_expression",
},
},
-- Not realy name of node
root_jsx_element = lu.set_default_preset({
split = {
format_tree = function(tsj)
-- TODO: checks if jsx_element is on one line
tsj:wrap({ left = "(", right = ")" })
end,
},
-- join = {
-- enable = false,
-- },
}),
},
javascript = {
["string"] = classnames,
parenthesized_expression = parenthesized_expression,
jsx_expression = lu.set_default_preset(),
},
},
})
end,
},
}

170
nvim/lua/plugins/jumps.lua Normal file
View file

@ -0,0 +1,170 @@
return {
{
"jinh0/eyeliner.nvim",
keys = { "t", "f", "T", "F" },
opts = {
highlight_on_key = true,
dim = true,
default_keymaps = false,
},
},
{
"mawkler/demicolon.nvim",
-- stylua: ignore start
keys = {
-- plugin
";", ",",
-- t/T/f/F key mappings
-- "t", "f", "T", "F",
-- lezy load key mappings
"]", "[",
-- key mappings to jump to diganostics. See demicolon.keymaps.create_default_diagnostic_keymaps
"]d", "[d",
-- quickfix
-- "]q", "[q", "]<C-q>", "[<C-q>",
-- local list
-- "]l", "[l", "]<C-l>", "]<C-l>",
-- spell
"]s", "[s",
-- fold
"]z", "[z",
-- gitsign
"]c", "[c",
-- neotest
"]t", "[t", "]T", "[T",
-- textobject
"]f", "[f", "]a", "[a", "]m", "[m"
},
-- stylua: ignore end
dependencies = {
"jinh0/eyeliner.nvim",
"nvim-treesitter/nvim-treesitter",
"nvim-treesitter/nvim-treesitter-textobjects",
},
opts = {
-- Create default keymaps
keymaps = {
-- Create t/T/f/F key mappings
horizontal_motions = false,
-- Create ]d/[d, etc. key mappings to jump to diganostics. See demicolon.keymaps.create_default_diagnostic_keymaps
diagnostic_motions = false,
-- Create ; and , key mappings
repeat_motions = "stateful",
-- Create ]q/[q/]<C-q>/[<C-q> and ]l/[l/]<C-l>/[<C-l> quickfix and location list mappings
list_motions = false,
-- Create `]s`/`[s` key mappings for jumping to spelling mistakes
spell_motions = true,
-- Create `]z`/`[z` key mappings for jumping to folds
fold_motions = true,
},
-- integrations = {
-- -- Integration with https://github.com/lewis6991/gitsigns.nvim
-- gitsigns = {
-- enabled = true,
-- keymaps = {
-- next = "]c",
-- prev = "[c",
-- },
-- },
-- -- Integration with https://github.com/nvim-neotest/neotest
-- neotest = {
-- enabled = true,
-- keymaps = {
-- test = {
-- next = "]t",
-- prev = "[t",
-- },
-- failed_test = {
-- next = "]T",
-- prev = "[T",
-- },
-- },
-- },
-- },
},
config = function(_, opts)
require("demicolon").setup(opts)
local function eyeliner_jump(key)
local forward = vim.list_contains({ "t", "f" }, key)
return function()
require("eyeliner").highlight({ forward = forward })
return require("demicolon.jump").horizontal_jump(key)()
end
end
local nxo = { "n", "x", "o" }
local key_opts = { expr = true }
vim.keymap.set(nxo, "f", eyeliner_jump("f"), key_opts)
vim.keymap.set(nxo, "F", eyeliner_jump("F"), key_opts)
vim.keymap.set(nxo, "t", eyeliner_jump("t"), key_opts)
vim.keymap.set(nxo, "T", eyeliner_jump("T"), key_opts)
end,
-- event = vim.g.post_load_events,
},
{
"folke/flash.nvim",
enabled = true,
-- event = "VeryLazy",
---@type Flash.Config
opts = {
modes = {
search = {
enabled = false,
},
char = {
enabled = false,
},
},
label = {
rainbow = {
enabled = false,
},
},
exclude = {
"notify",
"cmp_menu",
"noice",
"flash_prompt",
function(win)
return require("largefiles").is_large_file(win.buf, true)
end,
},
},
keys = {
{
"s",
mode = { "n", "x", "o" },
function()
require("flash").jump()
end,
desc = "Flash",
},
{
"S",
mode = { "n", "o", "x" },
function()
require("flash").treesitter()
end,
desc = "Flash Treesitter",
},
{
"r",
mode = "o",
function()
require("flash").remote()
end,
desc = "Remote Flash",
},
{
"R",
mode = { "o", "x" },
function()
require("flash").treesitter_search()
end,
desc = "Flash Treesitter Search",
},
},
},
}

View file

@ -0,0 +1 @@
return

194
nvim/lua/plugins/lang.lua Normal file
View file

@ -0,0 +1,194 @@
local fn = require("funcs")
local is_not_mini = require("funcs").is_not_mini
return {
{
"mfussenegger/nvim-lint",
lazy = true,
enabled = true,
config = function()
require("lint").linters_by_ft = vim.g.linter_by_ft
require("lint").linters.sqlfluff.args = {
"lint",
"--format=json",
"--dialect=postgres",
}
end,
},
{
"stevearc/conform.nvim",
cmd = { "ConformInfo" },
config = function()
require("conform").setup({
formatters_by_ft = vim.g.formatters_by_ft,
default_format_opts = {
lsp_format = "fallback",
},
-- Customize formatters
formatters = {
sqlfluff = {
prepend_args = { "--dialect", "postgres" },
},
},
})
end,
},
{
"folke/lazydev.nvim",
ft = "lua",
-- from nix
dev = true,
},
{
"mrcjkb/rustaceanvim",
cond = is_not_mini,
lazy = false,
ft = { "rust" },
-- from nix
dev = true,
},
{
name = "clangd_extenstions",
url = "https://git.sr.ht/~p00f/clangd_extensions.nvim",
cond = is_not_mini,
lazy = true,
},
{
url = "ray-x/go.nvim",
-- from nix
dev = true,
cond = is_not_mini,
opts = {
lsp_cfg = false,
diagnostic = false,
luasnip = false,
lsp_inlay_hints = {
enable = false,
},
},
config = function(_, opts)
require("go").setup(opts)
end,
event = { "CmdlineEnter" },
ft = { "go", "gomod" },
},
{ "b0o/schemastore.nvim", cond = is_not_mini, lazy = true },
{
"ranelpadon/python-copy-reference.vim",
cond = is_not_mini,
ft = { "python" },
init = function()
vim.g.python_remove_prefixes = { "src" }
end,
keys = {
{
"<leader>lcd",
":PythonCopyReferenceDotted<CR>",
desc = "Copy as: Python Dotted",
},
{
"<leader>lcp",
":PythonCopyReferencePytest<CR>",
desc = "Copy as: Pytest",
},
{
"<leader>lci",
":PythonCopyReferenceImport<CR>",
desc = "Copy as: Python Import",
},
},
},
{
"cuducos/yaml.nvim",
ft = { "yaml" }, -- optional
dependencies = {
"nvim-treesitter",
},
},
-- uncompiler
{
"p00f/godbolt.nvim",
config = function()
require("godbolt").setup()
end,
cmd = { "Godbolt", "GodboltCompiler" },
},
{
"nvimdev/phoenix.nvim",
enabled = false,
-- dev = true,
-- dir = "~/projects/phoenix.nvim",
init = function()
---Default configuration values for Phoenix
---@type PhoenixConfig
vim.g.phoenix = {
filetypes = { "*" },
dict = {
capacity = 50000, -- Store up to 50k words
min_word_length = 2, -- Ignore single-letter words
word_pattern = "[^%s%.%_:%p%d]+", -- Word pattern
},
-- snippet = vim.fn.stdpath("config") .. "/snippets",
}
end,
},
{
"JMarkin/gentags.lua",
enabled = false,
-- dev = true,
-- dir = "~/projects/jmarkin/gentags.lua",
branch = "feat/neovim-0.10",
cond = vim.fn.executable("ctags") == 1,
event = "VeryLazy",
opts = {
autostart = true,
async = true,
args = {
"--extras=+r+q",
"--exclude=\\.*",
"--exclude=.mypy_cache",
"--exclude=.ruff_cache",
"--exclude=.pytest_cache",
"--exclude=dist",
"--exclude=target",
"--exclude=build",
"--exclude=.git",
"--exclude=node_modules*",
"--exclude=BUILD",
"--exclude=vendor*",
"--exclude=*.min.*",
"--exclude=__file__",
"--exclude=.devenv",
},
},
cmd = {
"GenCTags",
"GenTagsEnable",
"GenTagsDisable",
},
},
{
"chrisgrieser/nvim-scissors",
opts = {
snippetDir = vim.fn.stdpath("config") .. "/snippets",
jsonFormatter = "jq",
},
keys = {
{
"<leader>Se",
function()
require("scissors").editSnippet()
end,
desc = "Snippet: Edit",
},
{
"<leader>Sn",
function()
require("scissors").addNewSnippet()
end,
mode = { "n", "x", "v" },
desc = "Snippet: New",
},
},
},
}

17
nvim/lua/plugins/lsp.lua Normal file
View file

@ -0,0 +1,17 @@
local is_not_mini = require("funcs").is_not_mini
return {
{
"neovim/nvim-lspconfig",
cond = is_not_mini,
event = vim.g.pre_load_events,
lazy = true,
},
{
"j-hui/fidget.nvim",
event = "LspAttach",
opts = {
-- options
},
},
}

111
nvim/lua/plugins/mini.lua Normal file
View file

@ -0,0 +1,111 @@
return {
{
"echasnovski/mini.icons",
event = "VeryLazy",
config = function()
require("mini.icons").setup()
MiniIcons.mock_nvim_web_devicons()
end,
},
-- Fast and feature-rich surround actions. For text that includes
-- surrounding characters like brackets or quotes, this allows you
-- to select the text inside, change or modify the surrounding characters,
-- and more.
{
"echasnovski/mini.surround",
keys = function(_, keys)
-- Populate the keys based on the user's options
local plugin = require("lazy.core.config").spec.plugins["mini.surround"]
local opts = require("lazy.core.plugin").values(plugin, "opts", false)
-- stylua: ignore start
local mappings = {
{ opts.mappings.add, desc = "Add surrounding", mode = { "n", "v" } },
{ opts.mappings.delete, desc = "Delete surrounding", mode = { "n" } },
{ opts.mappings.find, desc = "Find right surrounding" },
{ opts.mappings.find_left, desc = "Find left surrounding" },
{ opts.mappings.highlight, desc = "Highlight surrounding" },
{ opts.mappings.replace, desc = "Replace surrounding" },
{ opts.mappings.update_n_lines, desc = "Update `MiniSurround.config.n_lines`" },
}
-- stylua: ignore end
mappings = vim.tbl_filter(function(m)
return m[1] and #m[1] > 0
end, mappings)
return vim.list_extend(mappings, keys)
end,
opts = {
mappings = {
add = "gza", -- Add surrounding in Normal and Visual modes
delete = "gzd", -- Delete surrounding
find = "gzf", -- Find surrounding (to the right)
find_left = "gzF", -- Find surrounding to the left
highlight = "gzh", -- Highlight surrounding
replace = "gzr", -- Replace surrounding
update_n_lines = "gzn", -- Update `n_lines`
},
},
},
{
"echasnovski/mini.ai",
event = "ModeChanged",
opts = {
-- Table with textobject id as fields, textobject specification as values.
-- Also use this to disable builtin textobjects. See |MiniAi.config|.
custom_textobjects = nil,
-- Module mappings. Use `''` (empty string) to disable one.
mappings = {
-- Main textobject prefixes
around = "a",
inside = "i",
-- Next/last variants
around_next = "an",
inside_next = "in",
around_last = "al",
inside_last = "il",
-- Move cursor to corresponding edge of `a` textobject
goto_left = "g[",
goto_right = "g]",
},
-- Number of lines within which textobject is searched
n_lines = 50,
-- How to search for object (first inside current line, then inside
-- neighborhood). One of 'cover', 'cover_or_next', 'cover_or_prev',
-- 'cover_or_nearest', 'next', 'previous', 'nearest'.
search_method = "cover_or_next",
-- Whether to disable showing non-error feedback
silent = false,
},
},
{
"echasnovski/mini.misc",
config = function()
local misc = require("mini.misc")
misc.setup()
misc.setup_auto_root(vim.g.root_pattern)
local data = vim.fn.stdpath("data")
vim.opt.shadafile = (function()
local cwd = require("funcs").shorten_path(vim.fn.getcwd())
local file = vim.fs.joinpath(data, "project_shada", cwd)
vim.fn.mkdir(vim.fs.dirname(file), "p")
return file
end)()
vim.opt.viewdir = data .. "/" .. "view"
-- last position
misc.setup_restore_cursor({
ignore_filetype = { "largefile", "gitcommit", "gitrebase", "svn", "hgcommit" },
})
end,
},
}

30
nvim/lua/plugins/namu.lua Normal file
View file

@ -0,0 +1,30 @@
return {
{
"bassamsdata/namu.nvim",
-- dev = true,
keys = { { "<space>T", ":Namu ctags<cr>", desc = "Tagbar" } },
cmd = { "Namu" },
config = function()
require("namu").setup({
-- Enable the modules you want
namu_symbols = {
enable = true,
options = {
row_position = "bottom10_right",
},
},
namu_ctags = {
enable = true,
options = {
row_position = "bottom10_right",
},
},
-- Optional: Enable other modules if needed
colorscheme = {
enable = false,
},
ui_select = { enable = false }, -- vim.ui.select() wrapper
})
end,
},
}

View file

@ -0,0 +1,22 @@
local is_not_mini = require("funcs").is_not_mini
return {
"danymat/neogen",
cond = is_not_mini,
dependencies = "nvim-treesitter/nvim-treesitter",
config = function()
require("neogen").setup({
enabled = true,
input_after_comment = true,
snippet_engine = "nvim",
})
end,
cmd = "Neogen",
keys = {
{
"<leader>lD",
"<cmd>Neogen<cr>",
desc = "Lang: generate docs",
},
},
}

View file

@ -0,0 +1,25 @@
return {
{
"saghen/blink.pairs",
enabled = true,
-- from nix
dev = true,
opts = {
mappings = {
-- you can call require("blink.pairs.mappings").enable() and require("blink.pairs.mappings").disable() to enable/disable mappings at runtime
enabled = true,
-- see the defaults: https://github.com/Saghen/blink.pairs/blob/main/lua/blink/pairs/config/mappings.lua#L10
pairs = {},
},
highlights = {
enabled = true,
groups = vim.g.rainbow_delimiters_highlight,
matchparen = {
enabled = true,
group = "MatchParen",
},
},
debug = false,
},
},
}

View file

@ -0,0 +1,48 @@
return {
{
"stevearc/quicker.nvim",
ft = "qf",
opts = {
keys = {
{
">",
function()
require("quicker").expand({ before = 2, after = 2, add_to_existing = true })
end,
desc = "Expand quickfix context",
},
{
"<",
function()
require("quicker").collapse()
end,
desc = "Collapse quickfix context",
},
},
},
keys = {
{
"<space>Q",
function()
require("quicker").toggle()
end,
desc = "Toggle quickfix",
},
{
"<space>l",
function()
require("quicker").toggle({ loclist = true })
end,
desc = "Toggle loclist",
},
},
},
{
"kevinhwang91/nvim-bqf",
event = "VeryLazy",
opts = {
auto_enable = true,
auto_resize_height = true,
},
},
}

View file

@ -0,0 +1,77 @@
return {
"folke/snacks.nvim",
priority = 1000,
lazy = false,
---@type snacks.Config
opts = {
bigfile = { enabled = false },
dashboard = { enabled = false },
explorer = { enabled = false },
indent = { enabled = false },
input = { enabled = true },
notifier = {
enabled = true,
timeout = 1000,
level = vim.log.levels.WARN,
},
picker = { enabled = false },
quickfile = { enabled = true },
scope = { enabled = false },
scroll = { enabled = false },
statuscolumn = {
enabled = true,
folds = {
open = true, -- show open fold icons
git_hl = false, -- use Git Signs hl for fold icons
},
refresh = 200, -- ms
},
words = { enabled = false },
styles = {
notification = {
wo = { wrap = true }, -- Wrap notifications
},
},
},
keys = {
{
"<space>bd",
desc = "Buffers: delete current",
function()
Snacks.bufdelete.delete()
end,
},
{
"<space>bc",
desc = "Buffers: delete other",
function()
Snacks.bufdelete.other()
end,
},
{
"<leader>M",
desc = "Notifications",
function()
Snacks.notifier.show_history()
end,
},
{
"<leader>N",
desc = "Neovim News",
function()
Snacks.win({
file = vim.api.nvim_get_runtime_file("doc/news.txt", false)[1],
width = 0.6,
height = 0.6,
wo = {
spell = false,
wrap = false,
signcolumn = "yes",
statuscolumn = " ",
conceallevel = 3,
},
})
end,
},
},
}

View file

@ -0,0 +1,25 @@
return {
{
"mrjones2014/smart-splits.nvim",
event = "BufAdd",
opts = {
multiplexer_integration = "tmux",
},
-- from nix
dev = true,
-- lazy = false,
keys = {
-- stylua: ignore start
{ "<C-l>", function(...) require("smart-splits").move_cursor_right(...) end, silent = true, desc = "right", mode = { "n", "t", "v" } },
{ "<C-j>", function(...) require("smart-splits").move_cursor_down(...) end, silent = true, desc = "down", mode = { "n", "t", "v" }, },
{ "<C-k>", function(...) require("smart-splits").move_cursor_up(...) end, silent = true, desc = "top", mode = { "n", "t", "v" }, },
{ "<C-h>", function(...) require("smart-splits").move_cursor_left(...) end, silent = true, desc = "left", mode = { "n", "t", "v" }, },
{ "<A-l>", function(...) require("smart-splits").resize_right(...) end, silent = true, desc = "Resize right", mode = { "n", "t", "v" }, },
{ "<A-j>", function(...) require("smart-splits").resize_down(...) end, silent = true, desc = "Resize down", mode = { "n", "t", "v" }, },
{ "<A-k>", function(...) require("smart-splits").resize_up(...) end, silent = true, desc = "Resize up", mode = { "n", "t", "v" }, },
{ "<A-h>", function(...) require("smart-splits").resize_left(...) end, silent = true, desc = "Resize left", mode = { "n", "t", "v" }, },
-- stylua: ignore end
},
},
}

View file

@ -0,0 +1,126 @@
local function get_pos_lang(node)
local c = vim.api.nvim_win_get_cursor(0)
local range = { c[1] - 1, c[2], c[1] - 1, c[2] }
local buf = vim.api.nvim_get_current_buf()
local ok, parser = pcall(vim.treesitter.get_parser, buf, vim.treesitter.language.get_lang(vim.bo[buf].ft))
if not ok then
return ""
end
local current_tree = parser:language_for_range(range)
return current_tree:lang()
end
return {
{ "echasnovski/mini.splitjoin", lazy = true },
{
"Wansmer/treesj",
keys = {
{ "gj", ":lua require('treesj').join()<cr>", desc = "join lines", silent = true },
{ "gs", ":lua require('treesj').split()<cr>", desc = "split lines", silent = true },
{
"gm",
function()
local tsj_langs = require("treesj.langs")["presets"]
local lang = get_pos_lang()
if lang ~= "" and tsj_langs[lang] then
require("treesj").toggle()
else
require("mini.splitjoin").toggle()
end
end,
desc = "Toggle single/multiline by current position",
silent = true,
},
{
"gM",
function()
require("treesj").toggle({ split = { recursive = true }, join = { recursive = true } })
end,
desc = "Toggle single/multiline block of code",
},
},
dependencies = { "nvim-treesitter/nvim-treesitter" }, -- if you install parsers with `nvim-treesitter`
config = function()
local langs = require("treesj.langs").presets
local lu = require("treesj.langs.utils")
for _, nodes in pairs(langs) do
nodes.comment = {
both = {
fallback = function(_)
local res = require("mini.splitjoin").toggle()
if not res then
vim.cmd("normal! gww")
end
end,
},
}
end
local classnames = {
both = {
---@param tsn TSNode
enable = function(tsn)
local parent = tsn:parent()
if not parent or parent:type() ~= "jsx_attribute" then
return false
end
---@diagnostic disable-next-line: param-type-mismatch (jsx_attribute with no children does not exist.)
local attr_name = vim.treesitter.get_node_text(parent:child(0), 0)
return attr_name == "className"
end,
},
split = {
format_tree = function(tsj)
local str = tsj:child("string_fragment")
local words = vim.split(str:text(), " ")
tsj:remove_child("string_fragment")
for i, word in ipairs(words) do
tsj:create_child({ text = word }, i + 1)
end
end,
},
}
local parenthesized_expression = lu.set_preset_for_args()
require("treesj").setup({
max_join_length = 10000,
use_default_keymaps = false,
langs = {
tsx = {
["string"] = classnames,
interface_declaration = { target_nodes = { "object_type" } },
parenthesized_expression = parenthesized_expression,
jsx_expression = lu.set_default_preset(),
return_statement = {
target_nodes = {
["jsx_element"] = "root_jsx_element",
"jsx_self_closing_element",
"parenthesized_expression",
},
},
-- Not realy name of node
root_jsx_element = lu.set_default_preset({
split = {
format_tree = function(tsj)
-- TODO: checks if jsx_element is on one line
tsj:wrap({ left = "(", right = ")" })
end,
},
-- join = {
-- enable = false,
-- },
}),
},
javascript = {
["string"] = classnames,
parenthesized_expression = parenthesized_expression,
jsx_expression = lu.set_default_preset(),
},
},
})
end,
},
}

View file

@ -0,0 +1,21 @@
return {
{
"nanozuki/tabby.nvim",
event = "TabNew",
config = function()
require("tabby").setup({
option = {
lualine_theme = vim.g.lualine_theme or nil,
buf_name = { mode = "tail" },
},
})
end,
},
{
"echasnovski/mini.statusline",
event = vim.g.post_load_events,
config = function()
require("mini.statusline").setup()
end,
},
}

View file

@ -0,0 +1,12 @@
return {
{
"sheerun/vim-polyglot",
event = vim.g.pre_load_events,
init = function()
vim.cmd([[
syntax on
]])
vim.g.polyglot_disabled = { "ftdetect", "autoindent" }
end,
},
}

15
nvim/lua/plugins/term.lua Normal file
View file

@ -0,0 +1,15 @@
return {
{
"willothy/flatten.nvim",
version = "0.5.1",
enabled = true,
config = true,
opts = {
window = {
open = "tab",
},
},
lazy = false,
priority = 1001,
},
}

153
nvim/lua/plugins/ui.lua Normal file
View file

@ -0,0 +1,153 @@
return {
-- ui components
{ "MunifTanjim/nui.nvim", lazy = true },
{
"ibhagwan/smartyank.nvim",
enabled = true,
event = "ModeChanged",
opts = {
highlight = {
enabled = true, -- highlight yanked text
timeout = 100,
},
},
config = function(_, opts)
require("smartyank").setup(opts)
vim.api.nvim_create_autocmd("FocusGained", {
callback = function()
local loaded_content = vim.fn.getreg("+")
if loaded_content ~= "" then
vim.fn.setreg('"', loaded_content)
end
end,
})
end,
},
{
"DanilaMihailov/beacon.nvim",
-- enabled = false,
cond = function()
return not vim.g.neovide
end,
opts = {
enabled = function()
local line_count = vim.api.nvim_buf_line_count(vim.api.nvim_get_current_buf())
if line_count > 1000 then
return false
end
return true
end, --- (boolean | fun():boolean) check if enabled
speed = 2, --- integer speed at wich animation goes
width = 40, --- integer width of the beacon window
winblend = 70, --- integer starting transparency of beacon window :h winblend
fps = 60, --- integer how smooth the animation going to be
min_jump = 10, --- integer what is considered a jump. Number of lines
cursor_events = { "CursorMoved" }, -- table<string> what events trigger check for cursor moves
window_events = { "WinEnter", "FocusGained" }, -- table<string> what events trigger cursor highlight
highlight = { bg = "white", ctermbg = 15 }, -- vim.api.keyset.highlight table passed to vim.api.nvim_set_hl
},
event = { "BufAdd" },
},
{
"tzachar/local-highlight.nvim",
lazy = true,
-- enabled = false,
opts = {
insert_mode = false,
file_types = {},
hlgroup = "LocalHighlight",
},
init = function()
local fn = require("funcs")
local lf = require("largefiles")
vim.api.nvim_set_hl(0, "LocalHighlight", { underline = true })
fn.augroup("local-highlight-attach", {
vim.g.post_load_events,
{
pattern = "*",
callback = function(data)
if not lf.is_large_file(data.buf, true) then
require("local-highlight").attach(data.buf)
end
end,
},
})
end,
},
{
"lewis6991/whatthejump.nvim",
-- enabled = false,
keys = { "<C-i>", "<C-o>" },
},
{
"MeanderingProgrammer/render-markdown.nvim",
enabled = false,
ft = { "markdown", "codecompanion", "Avante" },
opts = {
render_modes = true,
file_types = { "markdown", "Avante", "codecompanion", "rmd" },
completions = { lsp = { enabled = true } },
debounce = 200,
code = {
style = "language",
highlight = nil,
highlight_inline = nil,
},
},
},
{
"ramilito/winbar.nvim",
event = "BufAdd",
opts = {
-- your configuration comes here, for example:
icons = true,
filetype_exclude = {
"vista",
"dbui",
"help",
"startify",
"dashboard",
"packer",
"neo-tree",
"neogitstatus",
"NvimTree",
"Trouble",
"alpha",
"lir",
"Outline",
"spectre_panel",
"toggleterm",
"TelescopePrompt",
"prompt",
"httpResult",
"rest_nvim_result",
"netrw",
"kulala_ui",
"AvanteInput",
"AvanteSelectedFiles",
"Avante",
"better_term",
"oil",
"DiffviewFiles",
},
background_color = "DiagnosticHint",
diagnostics = true,
buf_modified = true,
dir_levels = 2,
-- buf_modified_symbol = "M",
-- or use an icon
buf_modified_symbol = "",
dim_inactive = {
enabled = true,
highlight = "WinbarNC",
icons = true, -- whether to dim the icons
name = true, -- whether to dim the name
},
exclude_if = function()
return vim.b.no_winbar == true
end,
},
},
}

Some files were not shown because too many files have changed in this diff Show more