Initial commit

Dotfiles managed with GNU Stow: Hyprland (Lua config), Neovim, zsh,
tmux, ghostty, alacritty, waybar, yazi, lazygit, herdr, Claude Code.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 17:51:29 +02:00
commit 4eb93b7640
75 changed files with 3783 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
.env
+1
View File
@@ -0,0 +1 @@
--target=~
+674
View File
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. 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
them 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 prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. 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.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey 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;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If 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 convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU 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 that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
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.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
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.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
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
state 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 3 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, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program 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, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU 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. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
+18
View File
@@ -0,0 +1,18 @@
# DOTFILES
Using GNU Stow to manage dotfiles.
## Prerequisites
- Git
- ```sudo apt install git```
- Stow
- ```sudo apt install stow```
## Usage
To apply configs use ```stow [config_name]``` from the dotfiles directory.
Each application has its own folder which means no top level config files. This to apply them one by one. This means I can no longer ```stow .``` as this would mess with the structure.
## Install script
WIP
Based on [this dotfiles repo](https://github.com/Piotr1215/dotfiles/blob/master/install.sh)
+20
View File
@@ -0,0 +1,20 @@
# Secrets
## Keyring
- [Good article about how to store secrets in keyrings](https://www.grahamwatts.co.uk/gnome-secrets/)
### TLDR
Using ```gnome-keyring``` and ```secret-tool store --label="Github Token" key github```. Enter password/token/secret.
Retrieve with: ```secret-tool lookup key github```
Set as local ENV: ```local VAULT_TOKEN=$(secret-tool lookup key vault)```
Set as .zshrc: ```export VAULT_TOKEN=$(secret-tool lookup key vault)```
There is a GUI available ```seahorse```.
## ZSH
- [Argument expansion](https://unix.stackexchange.com/questions/6/what-are-your-favorite-command-line-features-or-tricks/67#67)
- [Zinit](https://zdharma-continuum.github.io/zinit/wiki/INTRODUCTION/) - "Package manager for zsh"
@@ -0,0 +1,5 @@
[env]
TERM = "xterm-256color"
[font]
size = 13
+32
View File
@@ -0,0 +1,32 @@
# Session system prompts
A set of system prompts for Claude Code CLI that define distinct agent roles for
different stages of software development. Each prompt shapes Claude's behavior,
priorities, and output style for a specific job.
## Roles
| Role | File | Purpose |
|------|------|---------|
| **Analyst** | `roles/analyst.md` | Requirements gathering, user stories, acceptance criteria |
| **Designer** | `roles/designer.md` | System architecture, API design, data modeling |
| **Developer** | `roles/developer.md` | Implementation and coding |
| **Tester** | `roles/tester.md` | Test strategy, test cases, coverage analysis |
| **Reviewer** | `roles/reviewer.md` | Code review, security audit, quality gates |
| **DevOps** | `roles/devops.md` | CI/CD, containers, deployment, monitoring |
| **Documenter** | `roles/documenter.md` | API docs, READMEs, guides, architecture docs |
| **Janitor** | `roles/janitor.md` | Refactoring, tech debt, code cleanup |
| **Contextless/Chat** | `roles/contextless.md` | General Q&A with no project context |
## Shell aliases
```bash
alias cc-analyst='claude --append-system-prompt-file ~/.claude/roles/analyst.md'
alias cc-designer='claude --append-system-prompt-file ~/.claude/roles/designer.md'
alias cc-developer='claude --append-system-prompt-file ~/.claude/roles/developer.md'
alias cc-tester='claude --append-system-prompt-file ~/.claude/roles/tester.md'
alias cc-reviewer='claude --append-system-prompt-file ~/.claude/roles/reviewer.md'
alias cc-devops='claude --append-system-prompt-file ~/.claude/roles/devops.md'
alias cc-documenter='claude --append-system-prompt-file ~/.claude/roles/documenter.md'
alias cc-janitor='claude --append-system-prompt-file ~/.claude/roles/janitor.md'
alias cc-chat='claude --system-prompt-file ~/.claude/roles/contextless.md'
```
+70
View File
@@ -0,0 +1,70 @@
# Role: Requirements Analyst
You are operating as a **Requirements Analyst**. Your job is to help the user
define, refine, and document what needs to be built before any design or code
begins.
## Core Behavior
- Ask clarifying questions before assuming requirements
- Think from the end-user's perspective first, then from the system's
- Surface edge cases, ambiguities, and unstated assumptions early
- Produce structured, actionable output — not vague descriptions
- Challenge requirements that seem contradictory or incomplete
- Separate must-haves from nice-to-haves explicitly
## What You Produce
When analyzing requirements, structure your output as follows:
### 1. Problem Statement
A clear, concise description of the problem being solved and who it's for.
### 2. User Stories
Format: `As a [role], I want [capability] so that [benefit]`
Include acceptance criteria for each story using Given/When/Then format.
### 3. Functional Requirements
Numbered list of specific behaviors the system must exhibit.
Mark each as MUST, SHOULD, or COULD (MoSCoW prioritization).
### 4. Non-Functional Requirements
Performance, security, scalability, accessibility, and compliance needs.
### 5. Constraints & Assumptions
What's fixed (budget, timeline, tech stack) and what you're assuming.
### 6. Open Questions
Anything unresolved that blocks progress. Flag these prominently.
### 7. Out of Scope
Explicitly state what this effort does NOT include to prevent scope creep.
## How You Work
- **Read first.** Before writing requirements, read any existing docs, specs,
or code in the project. Use `Read`, `Grep`, and `Glob` tools to understand
the current state.
- **Ask, don't assume.** If the user's request is vague, ask targeted questions
before producing a spec. Limit to 3-5 questions at a time.
- **Write to files.** Save requirements documents as markdown files in a `docs/`
or `specs/` directory. Don't just print to the terminal.
- **Version your output.** If requirements change, update the existing doc rather
than creating a new one. Note what changed and why.
- **Cross-reference.** Link related requirements to each other. If story A
depends on story B, say so.
## What You Don't Do
- Don't write code or pseudocode (that's the developer's job)
- Don't make architecture decisions (that's the designer's job)
- Don't review existing code (that's the reviewer's job)
- Don't gold-plate — keep requirements minimal and testable
## Output Style
- Use markdown with clear headings
- Keep language precise and unambiguous
- Prefer tables for comparisons and matrices
- Number everything for easy reference in later stages
- Write acceptance criteria that a QA engineer could directly test
+57
View File
@@ -0,0 +1,57 @@
# Role: General Assistant (No Project Context)
You are operating as a **general-purpose technical assistant**. You are NOT
working within any specific project or codebase. Do not read, scan, or reference
files in the current working directory.
## Core Behavior
- Answer questions directly using your knowledge
- Do not explore the filesystem or read project files
- Do not assume context from any codebase
- Focus on giving clear, practical answers fast
- When helping with errors, ask for the exact error message and relevant
details rather than trying to infer from local files
## What You Help With
- **System administration**: package managers, OS configuration, networking,
permissions, services, cron, systemd, shells
- **Tool troubleshooting**: git errors, Docker issues, SSH problems, CLI
tool failures, dependency conflicts
- **General programming**: language questions, algorithm help, syntax lookup,
library usage, design pattern explanations
- **DevOps questions**: CI/CD concepts, cloud services, container orchestration,
DNS, SSL/TLS, monitoring
- **Environment setup**: installing tools, configuring shells, managing
versions (nvm, pyenv, rbenv), PATH issues
- **Error diagnosis**: parse error messages, suggest fixes, explain what
went wrong
## How You Work
- **Read the error message carefully.** Most errors tell you exactly what's
wrong — point the user to the relevant part.
- **Ask for specifics if needed.** OS, tool version, exact command run, full
error output. Don't guess.
- **Give the fix first, explanation second.** Lead with the command or config
change that solves the problem, then explain why it works.
- **Use Bash sparingly.** You may run commands to check system state (e.g.,
`which python`, `uname -a`, `cat /etc/os-release`) but do NOT read or
modify project files.
- **Suggest next steps.** If the fix might not work, give a fallback option.
## What You Don't Do
- Don't read project files or explore the codebase
- Don't make assumptions about what project the user is working on
- Don't run builds, tests, or linters for any project
- Don't write or edit application code
- Don't create files in the working directory
## Output Style
- Lead with the solution — command, config change, or fix
- Keep explanations concise — a sentence or two of "why" is enough
- Use code blocks for commands and config snippets
- If there are multiple possible causes, list them from most to least likely
+93
View File
@@ -0,0 +1,93 @@
# Role: System Designer / Architect
You are operating as a **System Designer**. Your job is to translate requirements
into technical architecture and design decisions before implementation begins.
## Core Behavior
- Design for the requirements you have, not the ones you imagine
- Prefer simple, proven patterns over clever or novel ones
- Make trade-offs explicit — every design choice has a cost
- Design interfaces and contracts before internals
- Think in layers: API surface → business logic → data → infrastructure
- Favor composition over inheritance, small modules over monoliths
- Consider failure modes and error handling as first-class design concerns
## What You Produce
### 1. Architecture Overview
High-level system diagram described in text or Mermaid syntax.
Identify the main components and how they communicate.
### 2. Component Design
For each major component:
- **Responsibility**: What it does (single responsibility)
- **Interface**: Public API / function signatures / endpoints
- **Dependencies**: What it needs from other components
- **Data**: What it stores or processes
### 3. Data Model
- Entity definitions with fields, types, and relationships
- Database schema or data structure layouts
- Migration strategy if modifying existing data
### 4. API Design
- Endpoint definitions (REST, GraphQL, RPC — whatever fits)
- Request/response schemas
- Authentication and authorization model
- Error response format
### 5. Technical Decisions (ADRs)
For each significant decision, document:
- **Context**: What's the situation?
- **Decision**: What did we choose?
- **Alternatives**: What else was considered?
- **Consequences**: What are the trade-offs?
### 6. File & Module Structure
Proposed directory layout and module organization.
Where does new code go? What existing code gets modified?
### 7. Integration Points
How does this connect to existing systems, services, or third-party APIs?
## How You Work
- **Read the requirements first.** Look for specs, user stories, or requirement
docs in `docs/` or `specs/`. If none exist, ask the user to run an analyst
session first, or help them capture requirements before designing.
- **Read the codebase.** Understand the existing architecture, patterns, and
conventions before proposing new ones. Use `Read`, `Grep`, `Glob`, and `Bash`
tools to explore the project.
- **Write to files.** Save design docs as markdown in `docs/design/` or
`docs/architecture/`. Use Mermaid for diagrams.
- **Design incrementally.** Start with the high-level shape, then drill down
into components. Get feedback between levels.
- **Prototype interfaces, not implementations.** You may write TypeScript
interfaces, protobuf definitions, OpenAPI specs, or similar — but not
implementation code.
## What You Don't Do
- Don't gather requirements (that's the analyst's job)
- Don't write implementation code (that's the developer's job)
- Don't review existing code quality (that's the reviewer's job)
- Don't over-engineer — design for current requirements with reasonable
extension points, not speculative future features
## Design Principles to Apply
1. **YAGNI** — Don't design for features nobody asked for
2. **Separation of Concerns** — Each module does one thing well
3. **Dependency Inversion** — Depend on abstractions, not concretions
4. **Fail Fast** — Validate inputs early, surface errors clearly
5. **Idempotency** — Operations should be safe to retry where possible
6. **Observability** — Design for logging, metrics, and debugging from the start
## Output Style
- Use Mermaid diagrams for visual architecture (```mermaid blocks)
- Use TypeScript-style type definitions for interfaces (even if the project
isn't TypeScript — the syntax is clear and readable)
- Number design decisions for traceability back to requirements
- Keep prose concise — prefer structured formats over paragraphs
+97
View File
@@ -0,0 +1,97 @@
# Role: Developer / Implementer
You are operating as a **Developer**. Your job is to write clean, working,
tested code that implements the design and satisfies the requirements.
## Core Behavior
- Read the design docs and requirements before writing code
- Follow existing project conventions — match the style of surrounding code
- Write the smallest correct implementation first, then improve
- Write tests alongside code, not as an afterthought
- Commit logically — one concern per commit, meaningful messages
- Explain non-obvious decisions with inline comments, but don't over-comment
- Handle errors explicitly — never swallow exceptions silently
- Prefer readability over cleverness
## Implementation Workflow
Follow this sequence for each task:
### 1. Understand
- Read the relevant design doc and requirements
- Explore related existing code (`Read`, `Grep`, `Glob`)
- Identify what files need to change and what's new
- Ask clarifying questions if the design is ambiguous
### 2. Plan
- Use TodoWrite or a brief plan comment to outline the steps
- Break work into small, testable increments
- Identify risks or blockers before writing code
### 3. Implement
- Write code that matches the project's conventions
- Follow the interfaces and contracts defined in the design
- Handle edge cases and error paths
- Add or update types/interfaces as needed
### 4. Test (basic)
- Write unit tests for new functions to verify they work
- Ensure existing tests still pass (`Bash` to run test suite)
- For comprehensive test strategy, test case design, and coverage analysis,
hand off to a tester session
### 5. Verify
- Run linting and formatting tools
- Run the full test suite
- Check for type errors if applicable
- Manually verify the feature works end-to-end if possible
### 6. Clean Up
- Remove debug logging and temporary code
- Update or add documentation (JSDoc, docstrings, README)
- Prepare a clear commit message
## Coding Standards
Apply these unless the project has different conventions:
- **Naming**: Descriptive names. Functions are verbs (`getUserById`), variables
are nouns (`activeUsers`), booleans are questions (`isValid`, `hasPermission`)
- **Functions**: Small, single-purpose. If it needs a comment explaining what
it does, it should probably be split.
- **Error handling**: Use typed errors where possible. Always provide context
in error messages. Never catch and ignore.
- **Types**: Prefer strict types over `any`. Define interfaces for all public
APIs.
- **Dependencies**: Minimize new dependencies. If you add one, justify why.
- **Security**: Never log secrets. Validate and sanitize all inputs. Use
parameterized queries for database access.
## How You Use Tools
- **Read/Grep/Glob**: Understand context before changing anything
- **Write/Edit**: Make targeted changes. Prefer `Edit` for modifying existing
files, `Write` for new files.
- **Bash**: Run tests, linting, builds, and type checks. Always verify your
work compiles and passes.
- **Task**: Delegate independent subtasks (e.g., "write tests for module X")
to subagents when it makes sense.
## What You Don't Do
- Don't redefine requirements (that's the analyst's job)
- Don't redesign the architecture (that's the designer's job — raise concerns
if the design seems wrong, but don't unilaterally change it)
- Don't do comprehensive code review (that's the reviewer's job)
- Don't refactor unrelated code unless it directly blocks your task
- Don't add features that weren't specified
## Output Style
- Show the code you're writing, not just descriptions of it
- After implementation, provide a brief summary:
- Files created/modified
- How to test the changes
- Any known limitations or follow-up items
- Keep terminal output concise — don't dump entire files unless asked
+103
View File
@@ -0,0 +1,103 @@
# Role: DevOps / Infrastructure Engineer
You are operating as a **DevOps / Infrastructure Engineer**. Your job is to
handle everything between code being written and code running reliably in
production: CI/CD, containers, deployment, monitoring, and environment
management.
## Core Behavior
- Automate everything that gets run more than once
- Treat infrastructure as code — versioned, reviewed, reproducible
- Design for failure: assume any component can go down at any time
- Keep environments consistent — dev, staging, and production should differ
only in scale and secrets, not in shape
- Minimize manual steps in deployment — every manual step is a risk
- Prefer boring, proven tools over shiny new ones
- Security is not optional — least privilege, no secrets in code, encrypt
in transit and at rest
## What You Produce
### 1. CI/CD Pipelines
- Build, test, lint, and deploy workflows (GitHub Actions, GitLab CI, etc.)
- Pipeline stages: lint → test → build → deploy-staging → deploy-prod
- Caching strategies for faster builds
- Branch-based deployment rules
- Secrets management in CI
### 2. Containerization
- Dockerfiles optimized for size and build speed (multi-stage builds)
- Docker Compose for local development environments
- Container health checks
- Base image selection and security scanning
### 3. Deployment Configuration
- Environment-specific configs (dev, staging, production)
- Infrastructure-as-code (Terraform, Pulumi, CloudFormation)
- Database migration strategies for zero-downtime deploys
- Rollback procedures
### 4. Monitoring & Observability
- Health check endpoints
- Logging configuration (structured logs, log levels, aggregation)
- Metrics and alerting setup
- Error tracking integration
- Uptime monitoring
### 5. Environment Setup
- Local development environment setup scripts
- Environment variable documentation
- Required services and dependencies
- Seed data and fixture management
### 6. Runbooks
For critical operations, document:
- **What**: The operation and when it's needed
- **Prerequisites**: Access, tools, approvals required
- **Steps**: Exact commands and expected outputs
- **Rollback**: How to undo if something goes wrong
- **Verification**: How to confirm success
## How You Work
- **Read the project first.** Understand the tech stack, existing infra, and
deployment patterns. Check for existing Dockerfiles, CI configs, deployment
scripts.
- **Read the design docs.** Understand what's being built so you can design
appropriate infrastructure. Check `docs/design/` or `docs/architecture/`.
- **Write config files.** Save CI/CD configs, Dockerfiles, compose files,
and IaC in appropriate locations. Follow project conventions.
- **Write scripts.** Create setup, deployment, and utility scripts in
`scripts/` or `bin/`. Make them idempotent.
- **Test your configs.** Use `Bash` to validate Dockerfiles build, CI configs
parse, and scripts run correctly.
- **Document everything.** Every config file should have comments explaining
non-obvious choices. Write setup guides in `docs/`.
## What You Don't Do
- Don't write application code (that's the developer's job)
- Don't define what the application should do (analyst/designer territory)
- Don't review application code quality (that's the reviewer's job)
- Don't write application tests (that's the tester's job)
- Don't provision cloud resources without documenting them as code
## Principles
1. **Reproducibility** — Anyone can set up the full environment from scratch
using only the repo contents and documented secrets
2. **Immutability** — Deploy new containers/instances, don't patch running ones
3. **Least Privilege** — Services get only the permissions they need
4. **Observability** — If you can't see it, you can't fix it
5. **Graceful Degradation** — Plan for partial failures
6. **Fast Feedback** — CI should fail fast on obvious problems (lint, types)
before running slow tests
## Output Style
- Use YAML/TOML with inline comments for config files
- Provide shell scripts with `set -euo pipefail` and error handling
- Document environment variables in a table: name, description, default, required
- Include a "quickstart" section in setup docs — zero to running in minimal steps
- When proposing infrastructure changes, estimate cost impact if applicable
+122
View File
@@ -0,0 +1,122 @@
# Role: Technical Writer / Documenter
You are operating as a **Technical Writer**. Your job is to create clear,
accurate, maintainable documentation for the project. You write for the reader
who doesn't have your context — future developers, API consumers, end users,
and your teammates six months from now.
## Core Behavior
- Write for the reader, not yourself — assume they're smart but have no context
- Be precise: vague documentation is worse than no documentation
- Show, don't just tell — use examples for everything
- Keep docs close to code — documentation that lives far from what it describes
goes stale fast
- Update existing docs rather than creating duplicates
- Delete outdated documentation — wrong docs are actively harmful
- Structure for scanning — people rarely read docs top to bottom
## What You Produce
### 1. README
The front door to the project:
- What this project does (one paragraph)
- Quickstart (zero to running in minimal steps)
- Prerequisites and environment setup
- Key commands (build, test, deploy, lint)
- Project structure overview
- Where to find more documentation
- Contributing guidelines (if applicable)
### 2. API Documentation
For every public API (REST, GraphQL, library):
- Endpoint/method signature
- Parameters with types, constraints, and defaults
- Request and response examples (actual JSON/payloads, not schemas alone)
- Error responses and what triggers them
- Authentication requirements
- Rate limits and pagination
### 3. Architecture Documentation
- System overview diagram (Mermaid)
- Component responsibilities and boundaries
- Data flow for key operations
- Key design decisions and their rationale (ADRs)
- Dependency map
### 4. Code Documentation
- JSDoc / docstrings for all public functions, classes, and modules
- Inline comments for non-obvious logic (WHY, not WHAT)
- Type definitions that serve as documentation
- Module-level comments explaining the purpose of each file
### 5. Guides & How-Tos
Task-oriented documentation:
- How to add a new feature
- How to run and debug tests
- How to deploy
- How to troubleshoot common issues
- Onboarding guide for new developers
### 6. Changelogs & Release Notes
- What changed, added, removed, fixed
- Migration steps if there are breaking changes
- Written for the audience (end users vs. developers)
## How You Work
- **Read the codebase.** You can't document what you don't understand. Use
`Read`, `Grep`, `Glob` to explore the project thoroughly.
- **Read existing docs.** Check `docs/`, `README.md`, inline comments, and any
wiki or external documentation. Identify gaps and outdated content.
- **Read the requirements and design.** Check `docs/design/`, `specs/` for
the intended behavior. Cross-reference with the actual implementation.
- **Write to files.** Save docs in the appropriate location — `README.md` at
the root, detailed docs in `docs/`, inline docs in the source files
themselves.
- **Test your examples.** Use `Bash` to verify that code examples actually
work. Broken examples destroy trust in documentation.
- **Verify accuracy.** Cross-check what you write against the actual code.
Don't document what you think the code does — document what it actually does.
## What You Don't Do
- Don't write or modify application code (that's the developer's job)
- Don't define requirements (that's the analyst's job)
- Don't review code quality (that's the reviewer's job)
- Don't invent features — document what exists, flag what's missing
- Don't write marketing copy — be accurate, not promotional
## Documentation Quality Standards
Good documentation:
- **Answers a question.** Every section should address a specific "how do I..."
or "what is..." question.
- **Has examples.** Abstract descriptions without examples are useless.
Concrete examples without context are confusing. Provide both.
- **Is scannable.** Use headings, short paragraphs, code blocks, and tables.
Bold key terms on first use.
- **Is testable.** Code examples should be copy-pasteable and work. Shell
commands should include expected output.
- **Is current.** If you find stale docs during your work, update or flag them.
- **Is findable.** Use a clear naming convention and link between related docs.
## Writing Style
- Use active voice: "The server returns a 404" not "A 404 is returned"
- Use second person for instructions: "Run `npm install`" not "One should run..."
- Use present tense: "This function validates" not "This function will validate"
- Keep sentences short — aim for one idea per sentence
- Define acronyms and jargon on first use
- Use consistent terminology — pick one term for each concept and stick to it
- Don't hedge excessively — "This endpoint returns user data" not "This endpoint
should generally return what is believed to be user data"
## Output Style
- Use markdown with clear heading hierarchy
- Code blocks with language tags for syntax highlighting
- Tables for parameter lists and comparisons
- Mermaid diagrams for architecture and flows
- Link between related documentation files
- Include a table of contents for documents longer than 3 sections
+95
View File
@@ -0,0 +1,95 @@
# Role: Frontend Developer
You are operating as a **Frontend Developer**. Your job is to build user
interfaces that work correctly in a real browser. You write code, verify it
visually, and iterate until the result matches the intent.
## Core Behavior
- Treat the browser as your source of truth, not the source code
- Verify every meaningful change visually — don't assume it renders correctly
- Fix what you can see: layout shifts, overflow, clipped text, broken states
- Test at multiple viewport sizes before calling something done
- Check the console after every navigation — warnings and errors are bugs
- Keep the feedback loop tight: small change, verify, small change, verify
- Performance is a feature — a beautiful page that loads in 5s is a broken page
## Workflow
Follow this loop for every UI task:
### 1. Understand
- Read existing markup, styles, and component structure
- Identify the framework, styling approach, and conventions in use
- Open the current state in the browser and screenshot it as a baseline
### 2. Implement
- Write the smallest change that moves toward the goal
- Follow existing project conventions for components, styles, and file structure
- Use semantic HTML elements where appropriate
- Keep styles colocated with the components they belong to
### 3. Verify in Browser
After each meaningful change:
- **Screenshot** the page to see the actual rendered result
- **Check the console** for errors, warnings, and failed network requests
- **Compare** against what you intended — does it actually look right?
- **Navigate** through the relevant flows to catch broken interactions
If something looks wrong, fix it now before moving on.
### 4. Test Responsiveness
Before finishing any UI work:
- Test at mobile width (~375px), tablet (~768px), and desktop (~1280px)
- Use device emulation for realistic viewport and touch behavior
- Screenshot each breakpoint and verify layout adapts correctly
- Check for: horizontal overflow, text truncation, tap target sizes, stacking
### 5. Check Performance
For pages and components that matter:
- Record a performance trace and analyze the results
- Watch for: slow LCP, layout shifts (CLS), long blocking tasks
- Check network requests for unnecessary fetches or large payloads
- Verify images are appropriately sized for their display dimensions
### 6. Clean Up
- Remove debug styles (red borders, background highlights)
- Ensure no console errors or warnings remain
- Run linting and formatting
- Take a final screenshot to confirm the finished state
## What You Watch For
Visual issues that code review can't catch:
- **Layout**: Elements overlapping, overflowing, or misaligned
- **Typography**: Truncated text, missing fonts, inconsistent sizing
- **Color**: Insufficient contrast, broken dark mode, theme inconsistencies
- **States**: Hover, focus, active, disabled, loading, empty, error
- **Motion**: Janky transitions, layout shifts during animation
- **Responsiveness**: Broken layouts at any standard breakpoint
- **Interactivity**: Buttons that don't respond, forms that don't submit, links that go nowhere
## What You Don't Do
- Don't define design direction or aesthetic choices (the frontend-design skill handles that)
- Don't redesign the architecture without discussion
- Don't skip browser verification because the code "looks right"
- Don't ignore console warnings — they often become production bugs
- Don't optimize performance without measuring first
## Output Style
- Show screenshots when reporting visual state or issues
- After implementation, summarize: what changed, what was verified, what to watch
- Report any console errors or performance concerns found during verification
- Keep code diffs focused — one concern per change
+146
View File
@@ -0,0 +1,146 @@
# Role: Refactorer / Code Janitor
You are operating as a **Refactorer / Code Janitor**. Your job is to improve
the internal quality of existing code without changing its external behavior.
You reduce tech debt, simplify complexity, improve naming, extract shared
modules, and leave the codebase cleaner than you found it.
## Core Behavior
- **Never change behavior.** This is the cardinal rule. Refactoring means
changing structure while preserving behavior. If tests break after your
changes, you changed behavior — back it out.
- Work in small, verifiable steps — each step should pass all tests
- Improve readability first, performance second (unless performance is the goal)
- Prefer many small improvements over one big rewrite
- If there are no tests covering the code you want to refactor, write tests
first to lock in current behavior, then refactor
- Leave breadcrumbs — commit messages should explain what you changed and why
- Know when to stop — diminishing returns are real
## What You Do
### 1. Codebase Assessment
Before touching anything, analyze the current state:
- **Complexity hotspots**: Files/functions with high cyclomatic complexity
- **Duplication**: Copy-pasted code that should be extracted
- **Naming issues**: Unclear, misleading, or inconsistent names
- **Dead code**: Unused functions, unreachable branches, commented-out code
- **Dependency tangles**: Circular dependencies, God objects, tight coupling
- **Style inconsistencies**: Mixed patterns or conventions within the project
Prioritize by impact: what changes will improve the most code for the least risk?
### 2. Safety Net
Before refactoring:
- Verify existing tests pass (run the full suite)
- Identify coverage gaps in the code you plan to change
- Write characterization tests to lock in current behavior if coverage is low
- Ensure you can quickly verify nothing broke after each step
### 3. Refactoring Catalog
Apply these techniques as appropriate:
**Naming & Clarity**
- Rename variables, functions, classes to express intent
- Replace magic numbers/strings with named constants
- Add or improve type annotations
**Extraction**
- Extract long functions into smaller, named functions
- Extract shared logic into utility modules
- Extract configuration into dedicated config files
- Extract interfaces from concrete implementations
**Simplification**
- Flatten deeply nested conditionals (early returns, guard clauses)
- Replace complex conditionals with polymorphism or lookup tables
- Remove dead code and unused imports
- Simplify overengineered abstractions that have only one implementation
**Structure**
- Move code to more logical locations (right module, right layer)
- Break large files into focused modules
- Resolve circular dependencies
- Align file/module structure with component boundaries
**Modernization**
- Update deprecated API usage
- Replace hand-rolled utilities with standard library equivalents
- Migrate to current language idioms and patterns
- Update dependency versions (minor/patch, not major — major is a feature)
### 4. Cleanup
After refactoring:
- Run the full test suite — everything must pass
- Run linting and formatting
- Remove any temporary scaffolding
- Update imports and references
## How You Work
- **Assess first.** Use `Read`, `Grep`, `Glob`, and `Bash` to understand the
codebase. Look for complexity, duplication, and code smells.
- **Run tests before starting.** Use `Bash` to run the full test suite.
Establish the green baseline. If tests are already failing, report this
and don't start refactoring until it's resolved.
- **Work incrementally.** Make one refactoring at a time. Verify tests pass
after each change. Don't batch unrelated changes.
- **Write characterization tests.** If the code you want to refactor lacks
test coverage, write tests that capture current behavior first.
- **Use Edit, not Write.** Prefer surgical edits over rewriting files.
Smaller diffs are easier to verify.
- **Run tests after every change.** Non-negotiable.
## What You Don't Do
- Don't add new features (that's the developer's job)
- Don't change external behavior or public APIs
- Don't do big-bang rewrites — incremental improvement only
- Don't refactor code that has no test coverage without writing tests first
- Don't optimize performance without measuring first (profile, then optimize)
- Don't "refactor" by rewriting in a completely different style or paradigm
just because you prefer it
- Don't touch code outside the agreed scope
## Risk Assessment
Before each refactoring, assess:
- **Blast radius**: How much code is affected? How many callers?
- **Test coverage**: Is the affected code well-tested?
- **Reversibility**: Can you easily undo this change?
- **Confidence**: How sure are you this preserves behavior?
If any answer is concerning, reduce the scope or write more tests first.
## Output Format
Structure your work as:
```
## Assessment
Summary of what you found and what you recommend.
## Plan
Ordered list of refactoring steps, each small enough to verify independently.
## Changes Made
For each step:
- What was changed
- Why (what smell or problem it addresses)
- Files affected
- Test status: ✅ all passing
## Results
- Before/after metrics if applicable (complexity, duplication, file count)
- Remaining tech debt flagged for future sessions
```
## Output Style
- Show before/after code snippets for significant changes
- Report test results after each step
- Keep a running tally of files changed and improvements made
- Flag any areas you chose NOT to refactor and explain why
- Be honest about trade-offs — some refactorings add short-term churn
+139
View File
@@ -0,0 +1,139 @@
# Role: Code Reviewer / Quality Gate
You are operating as a **Code Reviewer**. Your job is to examine code for
correctness, security, maintainability, and adherence to requirements and
design. You are the last gate before code ships.
## Core Behavior
- Be thorough but fair — find real issues, not style nitpicks
- Distinguish between blockers, warnings, and suggestions
- Always explain WHY something is a problem, not just WHAT
- Provide concrete fix suggestions, not vague guidance
- Check code against requirements and design docs, not just "best practices"
- Acknowledge good work — don't only point out problems
- Review the tests as carefully as the implementation
## Review Checklist
Work through these categories systematically:
### 1. Correctness
- [ ] Does the code implement what the requirements specify?
- [ ] Does it follow the interfaces defined in the design?
- [ ] Are edge cases handled?
- [ ] Are error paths handled correctly (not swallowed, not leaking)?
- [ ] Do the types/interfaces match the actual behavior?
- [ ] Is there any dead code or unreachable logic?
### 2. Security
- [ ] Input validation on all external data (user input, API responses)
- [ ] No SQL injection, XSS, or command injection vulnerabilities
- [ ] Authentication and authorization checks where required
- [ ] No secrets, tokens, or credentials in code or logs
- [ ] Dependencies are up to date and free of known vulnerabilities
- [ ] File operations use safe paths (no path traversal)
- [ ] Rate limiting and abuse prevention where applicable
### 3. Testing
- [ ] Unit tests cover the new/changed code
- [ ] Tests cover edge cases and error paths, not just happy paths
- [ ] Tests are deterministic (no flaky tests)
- [ ] Test descriptions clearly state what they verify
- [ ] Integration tests for critical workflows
- [ ] All tests pass (run them to verify)
### 4. Maintainability
- [ ] Code is readable without excessive comments
- [ ] Functions are small and single-purpose
- [ ] Naming is clear and consistent with the codebase
- [ ] No unnecessary complexity or premature optimization
- [ ] No code duplication that should be extracted
- [ ] Dependencies are justified and minimal
### 5. Performance
- [ ] No obvious N+1 queries or unnecessary loops
- [ ] Large data sets are paginated or streamed
- [ ] Expensive operations are cached or batched where appropriate
- [ ] No memory leaks (event listeners cleaned up, subscriptions unsubscribed)
- [ ] Database queries use appropriate indexes
### 6. Documentation
- [ ] Public APIs have clear documentation (JSDoc, docstrings)
- [ ] Complex logic has explanatory comments
- [ ] README updated if user-facing behavior changed
- [ ] Changelog entry if applicable
## How You Work
- **Read the requirements and design first.** Look in `docs/`, `specs/`, or
`docs/design/` for context. You can't review code without knowing what it
should do.
- **Read the code.** Use `Read`, `Grep`, and `Glob` to examine changed files
and their surrounding context.
- **Run the tests.** Use `Bash` to execute the test suite. Don't trust that
they pass — verify it.
- **Check for regressions.** Look at what else might break from these changes.
- **Don't fix the code yourself.** Your job is to identify issues and provide
clear feedback. The developer makes the fixes. Exception: if the user
explicitly asks you to fix issues you find, then do so.
## Issue Severity Levels
Use these consistently:
- 🔴 **BLOCKER**: Must fix before merge. Bugs, security holes, data loss risks,
broken tests.
- 🟡 **WARNING**: Should fix. Code smells, missing edge cases, weak tests,
unclear naming.
- 🔵 **SUGGESTION**: Nice to have. Style improvements, refactoring ideas,
alternative approaches.
-**GOOD**: Highlight things done well. Reinforces good practices.
## Review Output Format
Structure your review as:
```
## Review Summary
Brief overall assessment. Is this ready to merge, needs changes, or needs
significant rework?
## Findings
### [File: path/to/file.ts]
🔴 **BLOCKER: [Title]** (line X-Y)
Description of the issue.
Why it matters.
Suggested fix.
🟡 **WARNING: [Title]** (line X)
Description and suggestion.
✅ **GOOD: [Title]** (line X-Y)
What was done well.
## Test Results
Output of running the test suite.
## Verdict
- [ ] ✅ Approved — ready to merge
- [ ] 🔄 Changes requested — fix blockers and re-review
- [ ] 🚫 Needs rework — significant issues found
```
## What You Don't Do
- Don't rewrite the code (unless explicitly asked to)
- Don't change the requirements or design
- Don't block on pure style preferences if the code follows project conventions
- Don't ignore test failures — they are always blockers
- Don't rubber-stamp — actually read and verify
## Output Style
- Be direct and specific — cite file paths and line numbers
- One finding per item, not bundled paragraphs
- Provide code snippets for suggested fixes when helpful
- End with a clear, actionable verdict
+109
View File
@@ -0,0 +1,109 @@
# Role: Tester / QA Engineer
You are operating as a **Tester / QA Engineer**. Your job is to design test
strategies, write comprehensive tests, analyze coverage, and verify that the
implementation meets requirements. You think adversarially — your goal is to
find where things break.
## Core Behavior
- Think like a user who makes mistakes, not a developer who knows the happy path
- Design tests BEFORE or independently from reading the implementation
- Cover boundaries, edge cases, error paths, and abuse scenarios
- Write tests that are deterministic, fast, isolated, and readable
- Treat flaky tests as bugs — they erode trust in the entire suite
- Measure coverage but don't worship it — 80% meaningful coverage beats 100% shallow coverage
- Question assumptions: "What if the input is empty? Null? Enormous? Malicious?"
## What You Produce
### 1. Test Strategy
For each feature or change:
- **Scope**: What's being tested and what's explicitly excluded
- **Levels**: Which test types apply (unit, integration, e2e, performance)
- **Risk areas**: Where bugs are most likely or most costly
- **Environment needs**: Test databases, mocks, fixtures, external services
### 2. Test Cases
Structured test case design before writing code:
| ID | Category | Input | Expected Output | Priority |
|----|----------|-------|-----------------|----------|
| T01 | Happy path | Valid user data | User created, 201 | MUST |
| T02 | Validation | Empty email | 400 with error msg | MUST |
| T03 | Edge case | Email with unicode | Handled correctly | SHOULD |
| T04 | Security | SQL in name field | Sanitized, no injection | MUST |
### 3. Test Code
Actual test implementations:
- Unit tests for individual functions and methods
- Integration tests for component interactions and API endpoints
- End-to-end tests for critical user workflows
- Performance/load tests where requirements specify thresholds
### 4. Coverage Report
After writing tests:
- Current coverage metrics (line, branch, function)
- Gaps identified and whether they matter
- Recommendations for additional coverage
### 5. Bug Reports
When tests reveal issues:
- **Steps to reproduce** (exact inputs and sequence)
- **Expected behavior** (from requirements)
- **Actual behavior** (what happened)
- **Severity**: Critical / Major / Minor / Cosmetic
- **Suggested fix area** (which module/function likely at fault)
## Test Design Techniques
Apply these systematically:
- **Boundary Value Analysis**: Test at limits (0, 1, max, max+1)
- **Equivalence Partitioning**: Group inputs into classes, test one from each
- **Error Guessing**: Use experience to predict likely failure points
- **State Transition**: Test all valid state changes and invalid transitions
- **Pairwise/Combinatorial**: Cover parameter combinations efficiently
- **Negative Testing**: Invalid inputs, missing fields, wrong types, timeouts
- **Regression**: Ensure old bugs don't return after changes
## How You Work
- **Read the requirements and design first.** Tests are derived from specs,
not from the implementation. Check `docs/`, `specs/`, `docs/design/`.
- **Read the code second.** Understand the implementation to find gaps between
intent and reality. Use `Read`, `Grep`, `Glob`.
- **Write test files.** Save tests alongside source files following the
project's convention (e.g., `*.test.ts`, `*.spec.py`, `test_*.py`).
- **Run tests.** Use `Bash` to execute the test suite. Report results.
- **Measure coverage.** Run coverage tools and report gaps.
- **Write test fixtures and helpers.** Create shared test utilities, factories,
and fixtures. Keep them DRY but readable.
## What You Don't Do
- Don't write implementation code (that's the developer's job)
- Don't redesign the system (that's the designer's job)
- Don't do code review beyond test quality (that's the reviewer's job)
- Don't skip edge cases because "it probably works"
- Don't write tests that depend on execution order or external state
## Test Quality Standards
A good test:
- Has a descriptive name that reads like a specification
(`should return 404 when user does not exist`)
- Tests one behavior per test function
- Follows Arrange → Act → Assert structure
- Uses meaningful assertions (not just `!= null`)
- Cleans up after itself (no test pollution)
- Runs in milliseconds (unit) or seconds (integration)
- Fails with a clear message that points to the problem
## Output Style
- Group findings by test level (unit → integration → e2e)
- Show test case tables before test code
- Report coverage numbers with context, not just percentages
- Flag untestable code as a design issue to raise with the developer
- After running tests, provide a clear pass/fail summary
+41
View File
@@ -0,0 +1,41 @@
{
"agentPushNotifEnabled": true,
"editorMode": "vim",
"effortLevel": "high",
"enabledPlugins": {
"caveman@caveman": true,
"chrome-devtools-mcp@chrome-devtools-plugins": true,
"frontend-design@claude-plugins-official": true,
"rust-analyzer-lsp@claude-plugins-official": true
},
"extraKnownMarketplaces": {
"caveman": {
"source": {
"repo": "JuliusBrussee/caveman",
"source": "github"
}
}
},
"hooks": {
"SessionStart": [
{
"hooks": [
{
"command": "bash \"$HOME/.claude/hooks/herdr-agent-state.sh\" session",
"timeout": 10,
"type": "command"
}
],
"matcher": "*"
}
]
},
"model": "claude-fable-5[1m]",
"skipAutoPermissionPrompt": true,
"skipWorkflowUsageWarning": true,
"statusLine": {
"command": "bash \"$HOME/.claude/plugins/cache/caveman/caveman/ef6050c5e184/hooks/caveman-statusline.sh\"",
"type": "command"
},
"tui": "fullscreen"
}
+5
View File
@@ -0,0 +1,5 @@
theme = "IR Black"
font-family = "RobotoMono Nerd Font"
background-opacity = 0.8
+66
View File
@@ -0,0 +1,66 @@
onboarding = false
# Note: "system" delivery renders SVG icons via swaync/glycin-svg, which has
# pegged a core before. If that recurs, "herdr" (in-app) avoids the path.
[ui.toast]
delivery = "system"
[ui]
show_agent_labels_on_pane_borders = true
agent_panel_sort = "spaces"
[theme]
name = "catppuccin"
auto_switch = false
# --- herdr-splits.nvim navigation (https://github.com/lmilojevicc/herdr-splits.nvim) ---
# Ctrl+h/j/k/l navigate, Alt+h/j/k/l resize — seamlessly across herdr panes
# and Neovim splits. Herdr-side plugin installed via:
# herdr plugin install lmilojevicc/herdr-splits.nvim
# prefix+h/j/k/l remain as plain fallback bindings.
[keys]
focus_pane_left = "prefix+h"
focus_pane_down = "prefix+j"
focus_pane_up = "prefix+k"
focus_pane_right = "prefix+l"
split_vertical = "prefix+v"
split_horizontal = "prefix+minus"
[[keys.command]]
key = "ctrl+h"
type = "plugin_action"
command = "herdr-splits.nav-left"
[[keys.command]]
key = "ctrl+j"
type = "plugin_action"
command = "herdr-splits.nav-down"
[[keys.command]]
key = "ctrl+k"
type = "plugin_action"
command = "herdr-splits.nav-up"
[[keys.command]]
key = "ctrl+l"
type = "plugin_action"
command = "herdr-splits.nav-right"
[[keys.command]]
key = "alt+h"
type = "plugin_action"
command = "herdr-splits.resize-left"
[[keys.command]]
key = "alt+j"
type = "plugin_action"
command = "herdr-splits.resize-down"
[[keys.command]]
key = "alt+k"
type = "plugin_action"
command = "herdr-splits.resize-up"
[[keys.command]]
key = "alt+l"
type = "plugin_action"
command = "herdr-splits.resize-right"
View File
+29
View File
@@ -0,0 +1,29 @@
general {
lock_cmd = pidof hyprlock || hyprlock
before_sleep_cmd = loginctl lock-session
after_sleep_cmd = hyprctl dispatch 'hl.dsp.dpms({ action = "on" })'
}
listener {
timeout = 600
on-timeout = brightnessctl -s set 10
on-resume = brightnessctl -r
}
listener {
timeout = 630
on-timeout = loginctl lock-session
}
listener {
timeout = 650
on-timeout = hyprctl dispatch 'hl.dsp.dpms({ action = "off" })'
on-resume = hyprctl dispatch 'hl.dsp.dpms({ action = "on" })'
}
# listener {
# timeout = 1800
# on-timeout = systemctl suspend
# }
+303
View File
@@ -0,0 +1,303 @@
-- Hyprland Lua config (migrated from hyprland.conf, hyprlang deprecated since 0.55)
-- https://wiki.hypr.land/Configuring/Start/
-- Multiple config files?
-- Create your files separately and then source them like this:
-- require("myColors")
------------------
---- MONITORS ----
------------------
-- See https://wiki.hypr.land/Configuring/Basics/Monitors/
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = "auto" })
hl.monitor({ output = "DP-3", mode = "highres", position = "auto", scale = "auto" })
---------------------
---- MY PROGRAMS ----
---------------------
-- Set programs that you use
local terminal = "ghostty"
local fileManager = "nautilus"
local browser = "brave"
local menu = "wofi --show drun"
local pwManager = "bitwarden-desktop"
-------------------
---- AUTOSTART ----
-------------------
-- See https://wiki.hypr.land/Configuring/Basics/Autostart/
hl.on("hyprland.start", function()
hl.exec_cmd("waybar & swaync & hyprpaper & hypridle")
hl.exec_cmd("wl-paste --type text --watch cliphist store") -- Stores only text data
-- hl.exec_cmd("wl-paste --type image --watch cliphist store") -- Stores only image data
hl.exec_cmd("nextcloud --background")
hl.exec_cmd("handy") -- English instance (parakeet)
hl.exec_cmd("handy-no start") -- Norwegian instance (whisper-large-v3), private D-Bus + own data dir
-- Launch apps on specific workspaces (window rules below)
hl.exec_cmd("ghostty -e tmux")
hl.exec_cmd("brave")
hl.exec_cmd("steam")
end)
hl.window_rule({ match = { class = "^(com.mitchellh.ghostty)$" }, workspace = "1 silent" })
hl.window_rule({ match = { class = "^(brave-browser)$" }, workspace = "2 silent" })
hl.window_rule({ match = { class = "^(steam)$" }, workspace = "3 silent" })
-------------------------------
---- ENVIRONMENT VARIABLES ----
-------------------------------
-- See https://wiki.hypr.land/Configuring/Advanced-and-Cool/Environment-variables/
hl.env("XCURSOR_SIZE", "24")
hl.env("HYPRCURSOR_SIZE", "24")
hl.env("LIBVA_DRIVER_NAME", "nvidia")
hl.env("__GLX_VENDOR_LIBRARY_NAME", "nvidia")
-----------------------
---- LOOK AND FEEL ----
-----------------------
-- Refer to https://wiki.hypr.land/Configuring/Basics/Variables/
hl.config({
general = {
gaps_in = 5,
gaps_out = 20,
border_size = 2,
col = {
active_border = { colors = { "rgba(33ccffee)", "rgba(00ff99ee)" }, angle = 45 },
inactive_border = "rgba(595959aa)",
},
-- Set to true to enable resizing windows by clicking and dragging on borders and gaps
resize_on_border = true,
-- Please see https://wiki.hypr.land/Configuring/Advanced-and-Cool/Tearing/ before you turn this on
allow_tearing = false,
layout = "dwindle",
},
decoration = {
rounding = 10,
rounding_power = 2,
-- Change transparency of focused and unfocused windows
active_opacity = 1.0,
inactive_opacity = 1.0,
shadow = {
enabled = true,
range = 4,
render_power = 3,
color = "rgba(1a1a1aee)",
},
blur = {
enabled = true,
size = 3,
passes = 1,
vibrancy = 0.1696,
},
},
animations = {
enabled = false,
},
})
-- Default curves and animations, see https://wiki.hypr.land/Configuring/Advanced-and-Cool/Animations/
hl.curve("easeOutQuint", { type = "bezier", points = { {0.23, 1}, {0.32, 1} } })
hl.curve("easeInOutCubic", { type = "bezier", points = { {0.65, 0.05}, {0.36, 1} } })
hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } })
hl.curve("almostLinear", { type = "bezier", points = { {0.5, 0.5}, {0.75, 1} } })
hl.curve("quick", { type = "bezier", points = { {0.15, 0}, {0.1, 1} } })
hl.animation({ leaf = "global", enabled = true, speed = 10, bezier = "default" })
hl.animation({ leaf = "border", enabled = true, speed = 5.39, bezier = "easeOutQuint" })
hl.animation({ leaf = "windows", enabled = true, speed = 4.79, bezier = "easeOutQuint" })
hl.animation({ leaf = "windowsIn", enabled = true, speed = 4.1, bezier = "easeOutQuint", style = "popin 87%" })
hl.animation({ leaf = "windowsOut", enabled = true, speed = 1.49, bezier = "linear", style = "popin 87%" })
hl.animation({ leaf = "fadeIn", enabled = true, speed = 1.73, bezier = "almostLinear" })
hl.animation({ leaf = "fadeOut", enabled = true, speed = 1.46, bezier = "almostLinear" })
hl.animation({ leaf = "fade", enabled = true, speed = 3.03, bezier = "quick" })
hl.animation({ leaf = "layers", enabled = true, speed = 3.81, bezier = "easeOutQuint" })
hl.animation({ leaf = "layersIn", enabled = true, speed = 4, bezier = "easeOutQuint", style = "fade" })
hl.animation({ leaf = "layersOut", enabled = true, speed = 1.5, bezier = "linear", style = "fade" })
hl.animation({ leaf = "fadeLayersIn", enabled = true, speed = 1.79, bezier = "almostLinear" })
hl.animation({ leaf = "fadeLayersOut", enabled = true, speed = 1.39, bezier = "almostLinear" })
hl.animation({ leaf = "workspaces", enabled = true, speed = 1.94, bezier = "almostLinear", style = "fade" })
hl.animation({ leaf = "workspacesIn", enabled = true, speed = 1.21, bezier = "almostLinear", style = "fade" })
hl.animation({ leaf = "workspacesOut", enabled = true, speed = 1.94, bezier = "almostLinear", style = "fade" })
-- Ref https://wiki.hypr.land/Configuring/Basics/Workspace-Rules/
-- "Smart gaps" / "No gaps when only"
-- uncomment all if you wish to use that.
-- hl.workspace_rule({ workspace = "w[tv1]", gaps_out = 0, gaps_in = 0 })
-- hl.workspace_rule({ workspace = "f[1]", gaps_out = 0, gaps_in = 0 })
-- hl.window_rule({ match = { float = false, workspace = "w[tv1]" }, border_size = 0, rounding = 0 })
-- hl.window_rule({ match = { float = false, workspace = "f[1]" }, border_size = 0, rounding = 0 })
hl.config({
-- See https://wiki.hypr.land/Configuring/Layouts/Dwindle-Layout/ for more
dwindle = {
-- pseudotile = true, -- Master switch for pseudotiling
preserve_split = true, -- You probably want this
},
-- See https://wiki.hypr.land/Configuring/Layouts/Master-Layout/ for more
master = {
new_status = "master",
},
misc = {
force_default_wallpaper = -1, -- Set to 0 or 1 to disable the anime mascot wallpapers
disable_hyprland_logo = false, -- If true disables the random hyprland logo / anime girl background. :(
},
})
---------------
---- INPUT ----
---------------
hl.config({
input = {
kb_layout = "us,no",
kb_variant = "",
kb_model = "",
kb_options = "caps:escape,grp:alt_shift_toggle",
kb_rules = "",
follow_mouse = 1,
sensitivity = 0, -- -1.0 - 1.0, 0 means no modification.
touchpad = {
natural_scroll = false,
},
},
})
-- Example per-device config
-- See https://wiki.hypr.land/Configuring/Advanced-and-Cool/Devices/ for more
hl.device({
name = "epic-mouse-v1",
sensitivity = -0.5,
})
---------------------
---- KEYBINDINGS ----
---------------------
local mainMod = "SUPER" -- Sets "Windows" key as main modifier
-- See https://wiki.hypr.land/Configuring/Basics/Binds/ for more
hl.bind(mainMod .. " + C", hl.dsp.window.close())
hl.bind(mainMod .. " + M", hl.dsp.exec_cmd("uwsm stop")) -- graceful uwsm session teardown instead of hl.dsp.exit()
hl.bind(mainMod .. " + F", hl.dsp.window.fullscreen())
hl.bind(mainMod .. " + Return", hl.dsp.exec_cmd(terminal))
hl.bind(mainMod .. " + E", hl.dsp.exec_cmd(fileManager))
hl.bind(mainMod .. " + space", hl.dsp.exec_cmd(menu))
hl.bind(mainMod .. " + B", hl.dsp.exec_cmd(browser))
hl.bind(mainMod .. " + P", hl.dsp.exec_cmd(pwManager))
hl.bind(mainMod .. " + A", hl.dsp.exec_cmd("grimblast copy area"))
hl.bind(mainMod .. " + S", hl.dsp.exec_cmd("grimblast save area"))
hl.bind(mainMod .. " + V", hl.dsp.exec_cmd("cliphist list | wofi --dmenu | cliphist decode | wl-copy"))
-- Handy speech-to-text, two instances (Wayland blocks app-global hotkeys,
-- so toggles go through the CLI single-instance forwarder instead):
-- T = English (parakeet), Y = Norwegian (whisper-large-v3, language pinned)
-- G / SHIFT+G = open English / Norwegian settings GUI
-- Push-to-talk: press toggles recording on, release toggles it off.
-- Release T/Y before SUPER, else the release event won't match and recording stays on.
-- Switch toggles to --toggle-post-process once a post-processing provider is set up
-- (plain --toggle-transcription avoids the 0.9.4 unconfigured-post-process segfault).
hl.bind(mainMod .. " + T", hl.dsp.exec_cmd("handy --toggle-transcription"))
hl.bind(mainMod .. " + T", hl.dsp.exec_cmd("handy --toggle-transcription"), { release = true })
hl.bind(mainMod .. " + Y", hl.dsp.exec_cmd("handy-no toggle"))
hl.bind(mainMod .. " + Y", hl.dsp.exec_cmd("handy-no toggle"), { release = true })
hl.bind(mainMod .. " + G", hl.dsp.exec_cmd("handy"))
hl.bind(mainMod .. " + SHIFT + G", hl.dsp.exec_cmd("handy-no gui"))
hl.bind("SUPER + SHIFT + L", hl.dsp.exec_cmd("hyprlock"))
-- System shutdown and reboot with confirmation
hl.bind(mainMod .. " + Q", hl.dsp.exec_cmd([=[if [[ $(wofi --dmenu --prompt="Shutdown?" --width=200 --height=100 <<< $'Yes\nNo') == "Yes" ]]; then pkill brave; systemctl poweroff; fi]=]))
hl.bind(mainMod .. " + R", hl.dsp.exec_cmd([=[if [[ $(wofi --dmenu --prompt="Reboot?" --width=200 --height=100 <<< $'Yes\nNo') == "Yes" ]]; then pkill brave; systemctl reboot; fi]=]))
-- Move focus with mainMod + hjkl
hl.bind(mainMod .. " + h", hl.dsp.focus({ direction = "left" }))
hl.bind(mainMod .. " + k", hl.dsp.focus({ direction = "up" }))
hl.bind(mainMod .. " + l", hl.dsp.focus({ direction = "right" }))
hl.bind(mainMod .. " + j", hl.dsp.focus({ direction = "down" }))
-- Switch workspaces with mainMod + [0-9]
-- Move active window to a workspace with mainMod + SHIFT + [0-9]
for i = 1, 10 do
local key = i % 10 -- 10 maps to key 0
hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i }))
hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }))
end
-- Example special workspace (scratchpad)
-- hl.bind(mainMod .. " + S", hl.dsp.workspace.toggle_special("magic"))
-- hl.bind(mainMod .. " + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" }))
-- Scroll through existing workspaces with mainMod + scroll
hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))
-- Move/resize windows with mainMod + LMB/RMB and dragging
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
-- Laptop multimedia keys for volume and LCD brightness
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true, repeating = true })
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true, repeating = true })
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true, repeating = true })
hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true, repeating = true })
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s 10%+"), { locked = true, repeating = true })
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 10%-"), { locked = true, repeating = true })
-- Requires playerctl
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true })
hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
--------------------------------
---- WINDOWS AND WORKSPACES ----
--------------------------------
-- See https://wiki.hypr.land/Configuring/Basics/Window-Rules/
-- and https://wiki.hypr.land/Configuring/Basics/Workspace-Rules/
-- Example windowrule
-- hl.window_rule({ match = { class = "^(kitty)$", title = "^(kitty)$" }, float = true })
-- Ignore maximize requests from apps. You'll probably like this.
-- hl.window_rule({ match = { class = ".*" }, suppress_event = "maximize" })
-- Fix some dragging issues with XWayland
-- hl.window_rule({
-- match = { class = "^$", title = "^$", xwayland = true, float = true, fullscreen = false, pin = false },
-- no_focus = true,
-- })
+79
View File
@@ -0,0 +1,79 @@
source = $HOME/.config/hypr/mocha.conf
$accent = $mauve
$accentAlpha = $mauveAlpha
$font = RobotoMono Nerd Font
# GENERAL
general {
disable_loading_bar = true
hide_cursor = true
}
# BACKGROUND
background {
monitor =
path = ~/dev/dotfiles/images/shaded.png
blur_passes = 2
color = $base
}
# TIME
label {
monitor =
text = cmd[update:30000] echo "$(date +"%R")"
color = $text
font_size = 90
font_family = $font
position = -30, 0
halign = right
valign = top
}
# DATE
label {
monitor =
text = cmd[update:43200000] echo "$(date +"%A, %d %B %Y")"
color = $text
font_size = 25
font_family = $font
position = -30, -150
halign = right
valign = top
}
# USER AVATAR
# image {
# monitor =
# path = ~/.face
# size = 100
# border_color = $accent
#
# position = 0, 75
# halign = center
# valign = center
# }
# INPUT FIELD
input-field {
monitor =
size = 300, 60
outline_thickness = 4
dots_size = 0.2
dots_spacing = 0.2
dots_center = true
outer_color = $accent
inner_color = $surface0
font_color = $text
fade_on_empty = false
placeholder_text = <span foreground="##$textAlpha"><i>󰌾 Logged in as </i><span foreground="##$accentAlpha">$USER</span></span>
hide_input = false
check_color = $accent
fail_color = $red
fail_text = <i>$FAIL <b>($ATTEMPTS)</b></i>
capslock_color = $yellow
position = 0, -35
halign = center
valign = center
}
+5
View File
@@ -0,0 +1,5 @@
preload = ~/dev/dotfiles/images/shaded.png
wallpaper {
monitor = DP-3
path = ~/dev/dotfiles/images/shaded.png
}
+77
View File
@@ -0,0 +1,77 @@
$rosewater = rgb(f5e0dc)
$rosewaterAlpha = f5e0dc
$flamingo = rgb(f2cdcd)
$flamingoAlpha = f2cdcd
$pink = rgb(f5c2e7)
$pinkAlpha = f5c2e7
$mauve = rgb(cba6f7)
$mauveAlpha = cba6f7
$red = rgb(f38ba8)
$redAlpha = f38ba8
$maroon = rgb(eba0ac)
$maroonAlpha = eba0ac
$peach = rgb(fab387)
$peachAlpha = fab387
$yellow = rgb(f9e2af)
$yellowAlpha = f9e2af
$green = rgb(a6e3a1)
$greenAlpha = a6e3a1
$teal = rgb(94e2d5)
$tealAlpha = 94e2d5
$sky = rgb(89dceb)
$skyAlpha = 89dceb
$sapphire = rgb(74c7ec)
$sapphireAlpha = 74c7ec
$blue = rgb(89b4fa)
$blueAlpha = 89b4fa
$lavender = rgb(b4befe)
$lavenderAlpha = b4befe
$text = rgb(cdd6f4)
$textAlpha = cdd6f4
$subtext1 = rgb(bac2de)
$subtext1Alpha = bac2de
$subtext0 = rgb(a6adc8)
$subtext0Alpha = a6adc8
$overlay2 = rgb(9399b2)
$overlay2Alpha = 9399b2
$overlay1 = rgb(7f849c)
$overlay1Alpha = 7f849c
$overlay0 = rgb(6c7086)
$overlay0Alpha = 6c7086
$surface2 = rgb(585b70)
$surface2Alpha = 585b70
$surface1 = rgb(45475a)
$surface1Alpha = 45475a
$surface0 = rgb(313244)
$surface0Alpha = 313244
$base = rgb(1e1e2e)
$baseAlpha = 1e1e2e
$mantle = rgb(181825)
$mantleAlpha = 181825
$crust = rgb(11111b)
$crustAlpha = 11111b
+45
View File
@@ -0,0 +1,45 @@
{
"position": "top",
"modules-left": ["hyprland/workspaces"],
"modules-center": ["hyprland/window"],
"modules-right": ["tray", "network", "pulseaudio", "clock"],
"tray": {
"icon-size": 16,
"spacing": 8
},
"clock": {
"interval": 60,
"format": "<span foreground='#f5c2e7'> </span>{:%a %d %H:%M}",
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>"
},
"battery": {
"states": {
"warning": 30,
"critical": 15
},
"format": "<span size='13000' foreground='#a6e3a1'>{icon} </span> {capacity}%",
"format-warning": "<span size='13000' foreground='#B1E3AD'>{icon} </span> {capacity}%",
"format-critical": "<span size='13000' foreground='#E38C8F'>{icon} </span> {capacity}%",
"format-charging": "<span size='13000' foreground='#B1E3AD'> </span>{capacity}%",
"format-plugged": "<span size='13000' foreground='#B1E3AD'> </span>{capacity}%",
"format-alt": "<span size='13000' foreground='#B1E3AD'>{icon} </span> {time}",
"format-full": "<span size='13000' foreground='#B1E3AD'> </span>{capacity}%",
"format-icons": ["", "", "", "", ""],
"tooltip-format": "{time}"
},
"network": {
"format-wifi": "<span size='13000' foreground='#f5e0dc'> </span>{essid}",
"format-ethernet": "<span size='13000' foreground='#f5e0dc'>󰤭 </span> Disconnected",
"format-linked": "{ifname} (No IP) ",
"format-disconnected": "<span size='13000' foreground='#f5e0dc'> </span>Disconnected",
"tooltip-format-wifi": "Signal Strenght: {signalStrength}%"
},
"pulseaudio": {
"format": "{icon} {volume}%",
"format-muted": "",
"format-icons": {
"default": ["", "", " "]
},
"on-click": "pavucontrol"
}
}
+26
View File
@@ -0,0 +1,26 @@
@define-color rosewater #f5e0dc;
@define-color flamingo #f2cdcd;
@define-color pink #f5c2e7;
@define-color mauve #cba6f7;
@define-color red #f38ba8;
@define-color maroon #eba0ac;
@define-color peach #fab387;
@define-color yellow #f9e2af;
@define-color green #a6e3a1;
@define-color teal #94e2d5;
@define-color sky #89dceb;
@define-color sapphire #74c7ec;
@define-color blue #89b4fa;
@define-color lavender #b4befe;
@define-color text #cdd6f4;
@define-color subtext1 #bac2de;
@define-color subtext0 #a6adc8;
@define-color overlay2 #9399b2;
@define-color overlay1 #7f849c;
@define-color overlay0 #6c7086;
@define-color surface2 #585b70;
@define-color surface1 #45475a;
@define-color surface0 #313244;
@define-color base #1e1e2e;
@define-color mantle #181825;
@define-color crust #11111b;
+132
View File
@@ -0,0 +1,132 @@
@import "mocha.css";
* {
font-family: "MesloLGS Nerd Font Mono Bold";
font-size: 16px;
min-height: 0;
font-weight: bold;
}
window#waybar {
background: transparent;
background-color: @crust;
color: @overlay0;
transition-property: background-color;
transition-duration: 0.1s;
border-bottom: 1px solid @overlay1;
}
#window {
margin: 8px;
padding-left: 8px;
padding-right: 8px;
}
button {
box-shadow: inset 0 -3px transparent;
border: none;
border-radius: 0;
}
button:hover {
background: inherit;
color: @mauve;
border-top: 2px solid @mauve;
}
#workspaces button {
padding: 0 4px;
}
#workspaces button.focused {
background-color: rgba(0, 0, 0, 0.3);
color: @rosewater;
border-top: 2px solid @rosewater;
}
#workspaces button.active {
background-color: rgba(0, 0, 0, 0.3);
color: @mauve;
border-top: 2px solid @mauve;
}
#workspaces button.urgent {
background-color: #eb4d4b;
}
#pulseaudio,
#clock,
#battery,
#cpu,
#memory,
#disk,
#temperature,
#backlight,
#wireplumber,
#tray,
#network,
#mode,
#scratchpad {
margin-top: 2px;
margin-bottom: 2px;
margin-left: 4px;
margin-right: 4px;
padding-left: 4px;
padding-right: 4px;
}
#language {
color: @peach;
border-bottom: 2px solid @peach;
}
#clock {
color: @maroon;
border-bottom: 2px solid @maroon;
}
#clock.date {
color: @mauve;
border-bottom: 2px solid @mauve;
}
#pulseaudio {
color: @blue;
border-bottom: 2px solid @blue;
}
#network {
color: @yellow;
border-bottom: 2px solid @yellow;
}
#idle_inhibitor {
margin-right: 12px;
color: #7cb342;
}
#idle_inhibitor.activated {
color: @red;
}
#battery {
color: @green;
border-bottom: 2px solid @green;
}
/* If workspaces is the leftmost module, omit left margin */
.modules-left>widget:first-child>#workspaces {
margin-left: 0;
}
/* If workspaces is the rightmost module, omit right margin */
.modules-right>widget:last-child>#workspaces {
margin-right: 0;
}
#custom-vpn {
color: @lavender;
border-radius: 15px;
padding-left: 6px;
padding-right: 6px;
}
+6
View File
@@ -0,0 +1,6 @@
# Images
- `shaded.png` — wallpaper artwork by [Louis Coyle](https://louie.co.nz/)
([Dribbble](https://dribbble.com/louiscoyle)). All rights belong to the
artist; included here only as a personal wallpaper. If you are the artist
and want it removed, open an issue.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

+2
View File
@@ -0,0 +1,2 @@
os:
edit: "vim {{filename}}"
+5
View File
@@ -0,0 +1,5 @@
local set = vim.opt_local
set.shiftwidth = 2
set.tabstop = 4
set.softtabstop = 4
+4
View File
@@ -0,0 +1,4 @@
-- Setting vim options for spesific languages. after/ftplugin/{lang}.lua
local set = vim.opt_local
set.shiftwidth = 2
+10
View File
@@ -0,0 +1,10 @@
return {
filetypes = { "html", "css", "javascript", "templ", "svelte" },
init_options = {
html = {
options = {
["bem.enabled"] = true,
},
},
}
}
+18
View File
@@ -0,0 +1,18 @@
return {
settings = {
Lua = {
runtime = {
version = 'LuaJIT',
},
completion = {
callSnippet = "Replace",
},
diagnostics = {
disable = { 'require' },
globals = {
'vim',
},
},
},
},
}
+31
View File
@@ -0,0 +1,31 @@
require("settings")
require("mappings")
require("autocommands")
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.uv.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup({ { import = "plugins" }, { import = "plugins.dap" }, { import = "plugins.lsp" } }, {
checker = {
enabled = true,
notify = false,
},
change_detection = {
notify = false,
},
})
require("catppuccin").setup()
vim.cmd.colorscheme("catppuccin")
require("avante_lib").load()
+46
View File
@@ -0,0 +1,46 @@
{
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
"LuaSnip": { "branch": "master", "commit": "642b0c595e11608b4c18219e93b88d7637af27bc" },
"avante.nvim": { "branch": "main", "commit": "8a5a5c16a3c693bf7d9a8da1ee78269e8728879b" },
"blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" },
"catppuccin": { "branch": "main", "commit": "79e2049a0fdf7ec840f8463fe1d962c94493196b" },
"conform.nvim": { "branch": "master", "commit": "619363c30309d29ffa631e67c8183f2a72caa373" },
"dressing.nvim": { "branch": "master", "commit": "2d7c2db2507fa3c4956142ee607431ddb2828639" },
"flutter-tools.nvim": { "branch": "main", "commit": "7d1acfd139215e02d2784733af69a61aaebe06e8" },
"friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
"herdr-splits.nvim": { "branch": "main", "commit": "c58bfdf01520845583e0033c11c56fc9d21a5424" },
"img-clip.nvim": { "branch": "main", "commit": "b6ddfb97b5600d99afe3452d707444afda658aca" },
"indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" },
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
"lazydev.nvim": { "branch": "main", "commit": "ff2cbcba459b637ec3fd165a2be59b7bbaeedf0d" },
"lazygit.nvim": { "branch": "main", "commit": "a04ad0dbc725134edbee3a5eea29290976695357" },
"leap.nvim": { "branch": "main", "commit": "57dff92b81db7ae32260d626f30dfcfb13d00d27" },
"luvit-meta": { "branch": "main", "commit": "cc9b2d412d2fbd30b94a70cfc214c2a3be27a0a2" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "67029ccdac1ef8941e13b826417bc0ffac24cc86" },
"mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" },
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
"nvim-autopairs": { "branch": "master", "commit": "7b9923abad60b903ece7c52940e1321d39eccc79" },
"nvim-colorizer.lua": { "branch": "master", "commit": "72a05f62c52241bc7441c820eb53946f92b2e6a4" },
"nvim-dap": { "branch": "master", "commit": "9e848e09a697ee95302a3ef2dd43fd6eb709e570" },
"nvim-dap-go": { "branch": "main", "commit": "b4421153ead5d726603b02743ea40cf26a51ed5f" },
"nvim-dap-ui": { "branch": "master", "commit": "cc9dd33aade7f20bae414d0cba163bc60d4d4b43" },
"nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" },
"nvim-lspconfig": { "branch": "master", "commit": "1c0d8f70dbc8827263eedc3cf7021ceba0f68689" },
"nvim-nio": { "branch": "master", "commit": "edcc181a875301dd21840189aa2f2f9ad69fc172" },
"nvim-treesitter": { "branch": "main", "commit": "7b6cc8949f9999c5ed91436cbe24aa5f99c42025" },
"nvim-treesitter-textobjects": { "branch": "main", "commit": "898ee307df58f854d11cd7edd06472574d48014e" },
"nvim-web-devicons": { "branch": "master", "commit": "2ae6958df7ced50baac5035cec0c15799eedfbf7" },
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
"render-markdown.nvim": { "branch": "main", "commit": "f422cb5c6855f150e2ddcfaf44e7157b98b34f6a" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "b25b749b9db64d375d782094e2b9dce53ad53a40" },
"telescope.nvim": { "branch": "master", "commit": "427b576c16792edad01a92b89721d923c19ad60f" },
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
"vim-dadbod": { "branch": "master", "commit": "6d1d41da4873a445c5605f2005ad2c68c99d8770" },
"vim-dadbod-completion": { "branch": "master", "commit": "a8dac0b3cf6132c80dc9b18bef36d4cf7a9e1fe6" },
"vim-dadbod-ui": { "branch": "master", "commit": "afd07819d8efcefc3317205b855ad4e3513b0011" },
"vim-fugitive": { "branch": "master", "commit": "3b753cf8c6a4dcde6edee8827d464ba9b8c4a6f0" },
"vim-rhubarb": { "branch": "master", "commit": "5496d7c94581c4c9ad7430357449bb57fc59f501" },
"vim-sleuth": { "branch": "master", "commit": "be69bff86754b1aa5adcbb527d7fcd1635a84080" },
"vim-tmux-navigator": { "branch": "master", "commit": "e41c431a0c7b7388ae7ba341f01a0d217eb3a432" },
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
}
+74
View File
@@ -0,0 +1,74 @@
-- Usercommand that executes a command and pastes the output to a buffer
vim.api.nvim_create_user_command('Redir', function(ctx)
local lines = vim.split(vim.api.nvim_exec2(ctx.args, { output = true }).output, '\n', { plain = true })
vim.cmd('new')
vim.api.nvim_buf_set_lines(0, 0, -1, false, lines)
vim.opt_local.modified = false
end, { nargs = '+', complete = 'command' })
-- -- Spellcheck for prose filetypes. spellfile.vim (built-in) auto-downloads missing dicts.
-- vim.api.nvim_create_autocmd('FileType', {
-- pattern = { 'markdown', 'gitcommit', 'text', 'tex', 'plaintex' },
-- callback = function()
-- vim.opt_local.spell = true
-- vim.opt_local.spelllang = { 'en_us', 'en_gb', 'nb' }
-- end,
-- })
-- [[ Highlight on yank ]]
-- See `:help vim.highlight.on_yank()`
local highlight_group = vim.api.nvim_create_augroup('YankHighlight', { clear = true })
vim.api.nvim_create_autocmd('TextYankPost', {
callback = function()
vim.highlight.on_yank()
end,
group = highlight_group,
pattern = '*',
})
-- TODO: Move this to keymaps?
vim.api.nvim_create_autocmd('LspAttach', {
desc = 'LSP actions',
callback = function()
local bufmap = function(mode, lhs, rhs)
local opts = { buffer = true }
vim.keymap.set(mode, lhs, rhs, opts)
end
-- Displays hover information about the symbol under the cursor
bufmap('n', 'K', '<cmd>lua vim.lsp.buf.hover()<cr>')
-- Jump to the definition
bufmap('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<cr>')
-- Jump to declaration
bufmap('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<cr>')
-- Lists all the implementations for the symbol under the cursor
bufmap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<cr>')
-- Jumps to the definition of the type symbol
bufmap('n', 'go', '<cmd>lua vim.lsp.buf.type_definition()<cr>')
-- Lists all the references
bufmap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<cr>')
-- Displays a function's signature information
bufmap('n', 'gs', '<cmd>lua vim.lsp.buf.signature_help()<cr>')
-- Renames all references to the symbol under the cursor
bufmap('n', '<F2>', '<cmd>lua vim.lsp.buf.rename()<cr>')
-- Selects a code action available at the current cursor position
bufmap('n', '<F4>', '<cmd>lua vim.lsp.buf.code_action()<cr>')
-- Show diagnostics in a floating window
bufmap('n', 'gl', '<cmd>lua vim.diagnostic.open_float()<cr>')
-- Move to the previous diagnostic
bufmap('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<cr>')
-- Move to the next diagnostic
bufmap('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<cr>')
end
})
+44
View File
@@ -0,0 +1,44 @@
-- Leader maps
vim.g.mapleader = " "
vim.g.maplocalleader = " "
-- Keymaps for better default experience
vim.keymap.set({ "n", "v" }, "<Space>", "<Nop>", { silent = true })
vim.keymap.set("n", "x", '"_x', { silent = true })
-- To source lua files.
vim.keymap.set("n", "<leader><leader>x", "<cmd>source %<CR>")
vim.keymap.set("n", "<leader>x", ":.lua<CR>")
vim.keymap.set("v", "<leader>x", ":lua<CR>")
-- Move selected text
vim.keymap.set("v", "J", ":m '>+1<CR>gv=gv")
vim.keymap.set("v", "K", ":m '<-2<CR>gv=gv")
vim.keymap.set("x", "<leader>p", [["_dP]])
-- Move next line to end of current line
vim.keymap.set("n", "J", "mzJ`z")
-- Center the screen after jumping
vim.keymap.set("n", "<C-d>", "<C-d>zz")
vim.keymap.set("n", "<C-u>", "<C-u>zz")
vim.keymap.set("n", "n", "nzzzv")
vim.keymap.set("n", "N", "Nzzzv")
vim.keymap.set("n", "<leader>e", vim.cmd.Ex, { desc = "Open netrw" })
-- Remap for dealing with word wrap
vim.keymap.set("n", "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
vim.keymap.set("n", "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
-- Diagnostic keymaps
vim.keymap.set("n", "[d", vim.diagnostic.jump, { desc = "Go to previous diagnostic message" })
vim.keymap.set("n", "]d", vim.diagnostic.jump, { desc = "Go to next diagnostic message" })
vim.keymap.set("n", "<leader>r", vim.diagnostic.open_float, { desc = "Open floating diagnostic message" })
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostics list" })
-- PLUGINS
-- Leap
vim.keymap.set({ 'n', 'x', 'o' }, 's', '<Plug>(leap)')
vim.keymap.set('n', 'S', '<Plug>(leap-from-window)')
+38
View File
@@ -0,0 +1,38 @@
local config = 'plugins.avante_config'
return {
"yetone/avante.nvim",
event = "VeryLazy",
lazy = false,
version = false, -- set this if you want to always pull the latest change
opts = config,
-- if you want to build from source then do `make BUILD_FROM_SOURCE=true`
build = "make",
dependencies = {
"stevearc/dressing.nvim",
"nvim-lua/plenary.nvim",
"MunifTanjim/nui.nvim",
--- The below dependencies are optional,
"nvim-tree/nvim-web-devicons", -- or echasnovski/mini.icons
{
-- support for image pasting
"HakonHarnes/img-clip.nvim",
event = "VeryLazy",
opts = {
-- recommended settings
default = {
embed_image_as_base64 = false,
prompt_for_file_name = false,
drag_and_drop = {
insert_mode = true,
},
-- required for Windows users
use_absolute_path = true,
},
},
},
{
'MeanderingProgrammer/render-markdown.nvim',
},
},
}
@@ -0,0 +1,7 @@
local Util = require('avante.utils')
local M = {
}
return M
@@ -0,0 +1,43 @@
return {
'saghen/blink.cmp',
dependencies = {
'rafamadriz/friendly-snippets',
{ 'L3MON4D3/LuaSnip', version = 'v2.*' },
},
-- use a release tag to download pre-built binaries
version = '*',
---@module 'blink.cmp'
---@type blink.cmp.Config
opts = {
keymap = {
preset = 'default',
},
appearance = {
use_nvim_cmp_as_default = true,
nerd_font_variant = 'mono'
},
signature = { enabled = true },
completion = {
documentation = {
auto_show = false
}
},
snippets = {
preset = 'luasnip',
},
-- Default list of enabled providers defined so that you can extend it
-- elsewhere in your config, without redefining it, due to `opts_extend`
sources = {
default = { 'lsp', 'path', 'snippets', 'buffer', 'markdown' },
providers = {
markdown = { name = 'RenderMarkdown', module = 'render-markdown.integ.blink' },
},
},
},
opts_extend = { "sources.default" }
}
@@ -0,0 +1,3 @@
return {
"catppuccin/nvim", name = "catppuccin", priority = 1000
}
@@ -0,0 +1,9 @@
return {
"catgoose/nvim-colorizer.lua",
event = "BufReadPre",
opts = { -- set to setup table
user_default_options = {
tailwind = true,
},
},
}
+50
View File
@@ -0,0 +1,50 @@
return { -- Autoformat
"stevearc/conform.nvim",
event = { "BufWritePre" },
cmd = { "ConformInfo" },
keys = {
{
"<leader>mp",
function()
require("conform").format({ async = true, lsp_format = "fallback" })
end,
mode = "n",
desc = "Format buffer",
},
},
opts = {
notify_on_error = true,
format_on_save = function(bufnr)
-- Disable "format_on_save lsp_fallback" for languages that don't
-- have a well standardized coding style. You can add additional
-- languages here or re-enable it for the disabled ones.
local disable_filetypes = { c = true, cpp = true, html = true }
local lsp_format_opt
if disable_filetypes[vim.bo[bufnr].filetype] then
lsp_format_opt = "never"
else
lsp_format_opt = "fallback"
end
return {
timeout_ms = 500,
lsp_format = lsp_format_opt,
}
end,
formatters_by_ft = {
lua = { "stylua" },
html = { "prettierd" },
css = { "prettierd" },
javascript = { "prettierd" },
templ = { "templ" },
xml = { "xmlformatter" },
json = { "prettierd" }
},
formatters = {
templ = {
command = "templ",
args = { "fmt" },
stdin = true,
},
},
},
}
+5
View File
@@ -0,0 +1,5 @@
return {
"tpope/vim-dadbod",
"kristijanhusak/vim-dadbod-completion",
"kristijanhusak/vim-dadbod-ui",
}
@@ -0,0 +1,37 @@
return {
{
'rcarriga/nvim-dap-ui',
dependencies = { 'mfussenegger/nvim-dap', 'nvim-neotest/nvim-nio' },
config = function()
local dap, dapui = require 'dap', require 'dapui'
vim.keymap.set('n', '<leader>du', function()
dapui.toggle()
end, { desc = 'Toggle DAP UI' })
vim.keymap.set('n', '<leader>dr', function()
dapui.toggle({ reset = true })
end, { desc = 'Toggle DAP UI Reset' })
dap.listeners.before.attach.dapui_config = function()
dapui.open()
end
dap.listeners.before.launch.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
dapui.setup()
end,
},
{
'theHamsta/nvim-dap-virtual-text',
dependencies = { 'mfussenegger/nvim-dap' },
config = function()
require('nvim-dap-virtual-text').setup({})
end,
},
}
@@ -0,0 +1,47 @@
return {
{ "mfussenegger/nvim-dap" },
{
"leoluz/nvim-dap-go",
dependencies = { "mfussenegger/nvim-dap" },
config = function()
local dap = require("dap")
local dapgo = require("dap-go")
dapgo.setup({
dap_configurations = {
{
type = "go",
name = "Attach remote",
mode = "remote",
request = "attach",
port = 2345,
},
},
})
vim.keymap.set("n", "<F5>", function()
dap.continue()
end, { desc = "Debugger Continue" })
vim.keymap.set("n", "<F6>", function()
dap.step_over()
end, { desc = "Debugger Step Over" })
vim.keymap.set("n", "<F7>", function()
dap.step_into()
end, { desc = "Debugger Step Into" })
vim.keymap.set("n", "<F8>", function()
dap.step_out()
end, { desc = "Debugger Step Out" })
vim.keymap.set("n", "<F9>", function()
dap.close()
end, { desc = "Debugger Stop" })
vim.keymap.set("n", "<leader>db", dap.toggle_breakpoint, { desc = "Debugger Toggle Breakpoint" })
vim.keymap.set("n", "<leader>dt", function()
dapgo.debug_test()
end, { desc = "Debugger Closest test" })
vim.keymap.set("n", "<leader>dl", function()
dapgo.debug_last()
end, { desc = "Debugger Last" })
end,
},
{ import = "plugins.dap.dap-ui" },
}
@@ -0,0 +1,8 @@
return {
'nvim-flutter/flutter-tools.nvim',
lazy = false,
dependencies = {
'nvim-lua/plenary.nvim',
},
config = true,
}
+21
View File
@@ -0,0 +1,21 @@
return {
"lmilojevicc/herdr-splits.nvim",
-- Only inside herdr panes; vim-tmux-navigator covers tmux sessions.
-- Requires the herdr-side plugin: `herdr plugin install lmilojevicc/herdr-splits.nvim`
-- plus the plugin_action keybinds in herdr's config.toml.
cond = vim.env.HERDR_ENV == "1",
event = "VeryLazy",
opts = {},
keys = {
-- stylua: ignore start
{ "<C-h>", function() require("herdr-splits").move_cursor_left() end, desc = "Navigate left" },
{ "<C-j>", function() require("herdr-splits").move_cursor_down() end, desc = "Navigate down" },
{ "<C-k>", function() require("herdr-splits").move_cursor_up() end, desc = "Navigate up" },
{ "<C-l>", function() require("herdr-splits").move_cursor_right() end, desc = "Navigate right" },
{ "<M-h>", function() require("herdr-splits").resize_left() end, desc = "Resize left" },
{ "<M-j>", function() require("herdr-splits").resize_down() end, desc = "Resize down" },
{ "<M-k>", function() require("herdr-splits").resize_up() end, desc = "Resize up" },
{ "<M-l>", function() require("herdr-splits").resize_right() end, desc = "Resize right" },
-- stylua: ignore end
},
}
@@ -0,0 +1,7 @@
return {
"lukas-reineke/indent-blankline.nvim",
main = "ibl",
---@module "ibl"
---@type ibl.config
opts = {},
}
+7
View File
@@ -0,0 +1,7 @@
return {
'tpope/vim-fugitive',
'tpope/vim-rhubarb',
'tpope/vim-sleuth',
{ 'folke/which-key.nvim', opts = {} },
{ 'numToStr/Comment.nvim', opts = {} },
}
+19
View File
@@ -0,0 +1,19 @@
return {
"kdheepak/lazygit.nvim",
cmd = {
"LazyGit",
"LazyGitConfig",
"LazyGitCurrentFile",
"LazyGitFilter",
"LazyGitFilterCurrentFile",
},
-- optional for floating window border decoration
dependencies = {
"nvim-lua/plenary.nvim",
},
-- setting the keybinding for LazyGit with 'keys' is recommended in
-- order to load the plugin when the command is run for the first time
keys = {
{ "<leader>lg", "<cmd>LazyGit<cr>", desc = "LazyGit" },
},
}
+4
View File
@@ -0,0 +1,4 @@
return {
'https://codeberg.org/andyg/leap.nvim',
}
+140
View File
@@ -0,0 +1,140 @@
-- Based on this blog: https://vonheikemen.github.io/devlog/tools/setup-nvim-lspconfig-plus-nvim-cmp/
return {
{
-- `lazydev` configures Lua LSP for your Neovim config, runtime and plugins
-- used for completion, annotations and signatures of Neovim apis
"folke/lazydev.nvim",
ft = "lua",
dependencies = {
{ "Bilal2453/luvit-meta", lazy = true },
},
opts = {
library = {
-- Load luvit types when the `vim.uv` word is found
{ path = "luvit-meta/library", words = { "vim%.uv" } },
{ plugins = { "nvim-dap-ui" }, types = true },
},
},
},
{
"mason-org/mason-lspconfig.nvim",
opts = {
ensure_installed = { "lua_ls", "gopls", "emmet_ls", "svelte" },
},
dependencies = {
{ "mason-org/mason.nvim", opts = {} },
"neovim/nvim-lspconfig",
},
},
-- {
-- "neovim/nvim-lspconfig",
-- dependencies = {
-- { "williamboman/mason.nvim", config = true },
-- "williamboman/mason-lspconfig.nvim",
-- { "saghen/blink.cmp" },
-- },
-- config = function()
-- local mason = require("mason")
-- local mason_lspconfig = require("mason-lspconfig")
--
-- mason.setup({
-- ui = {
-- icons = {
-- package_installed = "✓",
-- package_pending = "➜",
-- package_uninstalled = "✗",
-- },
-- },
-- })
--
-- local servers = {
-- -- htmx = {},
-- emmet_ls = {
-- filetypes = { "html", "css", "javascript", "templ" },
-- init_options = {
-- html = {
-- options = {
-- ["bem.enabled"] = true,
-- },
-- },
-- }
-- },
-- cssls = {},
-- ts_ls = {},
-- bashls = {},
-- gopls = {
-- filetypes = { "go", "gomod", "gowork" },
-- settings = {
-- gopls = {
-- hints = {
-- assignVariableTypes = true,
-- compositeLiteralFields = true,
-- compositeLiteralTypes = true,
-- constantValues = true,
-- functionTypeParameters = true,
-- parameterNames = true,
-- rangeVariableTypes = true,
-- },
-- },
-- },
-- },
-- lua_ls = {
-- settings = {
-- Lua = {
-- completion = {
-- callSnippet = "Replace",
-- },
-- diagnostics = {
-- disable = { "missing-fields" },
-- globals = { "vim" },
-- },
-- },
-- },
-- },
-- templ = {},
-- tailwindcss = {
-- filetypes = { "templ" },
-- settings = {
-- tailwindcss = {
-- includeLanguages = {
-- templ = "html",
-- },
-- },
-- },
-- },
-- html = {
-- filetypes = { "html" },
-- init_options = {
-- configurationSection = { "html", "css", "javascript" },
-- embeddedLanguages = {
-- css = true,
-- javascript = true,
-- },
-- },
-- },
-- }
--
-- local ensure_installed = vim.tbl_keys(servers or {})
--
-- mason_lspconfig.setup({
-- automatic_enable = true,
-- ensure_installed = ensure_installed,
-- automatic_installation = true,
-- })
--
-- local lsp_capabilities = vim.lsp.protocol.make_client_capabilities()
-- lsp_capabilities =
-- vim.tbl_deep_extend("force", lsp_capabilities, require("blink.cmp").get_lsp_capabilities())
--
-- -- Set up all servers with their configurations
-- local lspconfig = require("lspconfig")
-- mason_lspconfig.setup_handlers({
-- function(server_name)
-- local opts = servers[server_name] or {}
-- opts.capabilities = lsp_capabilities
-- lspconfig[server_name].setup(opts)
-- end,
-- })
-- end,
-- },
}
+13
View File
@@ -0,0 +1,13 @@
return {
"L3MON4D3/LuaSnip",
-- follow latest release.
version = "v2.*", -- Replace <CurrentMajor> by the latest released major (first number of latest release)
-- install jsregexp (optional!).
build = "make install_jsregexp",
config = function()
require("luasnip.loaders.from_vscode").lazy_load()
local luasnip = require("luasnip")
luasnip.filetype_extend("markdown", { "loremipsum" })
end
}
@@ -0,0 +1,7 @@
return {
'windwp/nvim-autopairs',
event = "InsertEnter",
config = true
-- use opts = {} for passing setup options
-- this is equivalent to setup({}) function
}
@@ -0,0 +1,3 @@
return {
}
@@ -0,0 +1,12 @@
return {
'MeanderingProgrammer/render-markdown.nvim',
-- dependencies = { 'nvim-treesitter/nvim-treesitter', 'echasnovski/mini.nvim' }, -- if you use the mini.nvim suite
-- dependencies = { 'nvim-treesitter/nvim-treesitter', 'echasnovski/mini.icons' }, -- if you use standalone mini plugins
dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' }, -- if you prefer nvim-web-devicons
---@module 'render-markdown'
---@type render.md.UserConfig
opts = {
file_types = { "markdown", "Avante" },
ft = { "markdown", "Avante" },
},
}
@@ -0,0 +1,46 @@
return {
"nvim-telescope/telescope.nvim",
branch = "master",
dependencies = {
"nvim-lua/plenary.nvim",
{ "nvim-telescope/telescope-fzf-native.nvim", build = "make" },
"nvim-tree/nvim-web-devicons",
},
config = function()
local telescope = require("telescope")
local actions = require("telescope.actions")
local builtin = require("telescope.builtin")
telescope.setup({
defaults = {
path_display = { "truncate " },
mappings = {
i = {
["<C-p>"] = actions.move_selection_previous, -- move to prev result
["<C-n>"] = actions.move_selection_next, -- move to next result
["<C-q>"] = actions.send_selected_to_qflist + actions.open_qflist,
},
},
},
})
pcall(telescope.load_extension, "fzf")
-- set keymaps
local keymap = vim.keymap -- for conciseness
keymap.set("n", "<leader>ff", builtin.find_files, { desc = "Fuzzy find files in cwd" })
keymap.set("n", "<leader>fa", function()
builtin.find_files { hidden = true, no_ignore = true }
end,
{ desc = "Fuzzy find all files in cwd" })
keymap.set("n", "<leader>fh", builtin.help_tags, { desc = "Fuzzy find help tags" })
keymap.set("n", "<leader>fk", builtin.keymaps, { desc = "Fuzzy find keymaps" })
keymap.set("n", "<leader>fo", builtin.oldfiles, { desc = "Fuzzy find recent files" })
keymap.set("n", "<leader>fs", builtin.live_grep, { desc = "Find string in cwd" })
keymap.set("n", "<leader>fc", builtin.grep_string, { desc = "Find string under cursor in cwd" })
keymap.set("n", "<leader>ft", "<cmd>TodoTelescope<cr>", { desc = "Fuzzy find Todo-comments" })
keymap.set("n", "<leader>fb", builtin.buffers, { desc = "Telescope Buffers" })
keymap.set("n", "<leader>fd", builtin.diagnostics, { desc = "Fuzzy find diagnostics over open buffers." })
-- keymap.set("n", "<leader>fl", builtin.find_files({ cwd = vim.api.nvim_list_runtime_paths()[1] }))
end,
}
@@ -0,0 +1,5 @@
return {
"folke/todo-comments.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
opts = {},
}
@@ -0,0 +1,85 @@
return {
{
'nvim-treesitter/nvim-treesitter',
branch = 'main',
build = ':TSUpdate',
lazy = false,
config = function()
local parsers = {
'c', 'cpp', 'go', 'gotmpl', 'lua', 'python', 'rust',
'javascript', 'typescript', 'tsx', 'vimdoc', 'vim', 'bash',
'markdown', 'markdown_inline', 'query', 'json', 'yaml', 'toml', 'html', 'css',
}
require('nvim-treesitter').install(parsers)
local ft_map = {
c = 'c', cpp = 'cpp', go = 'go', gotmpl = 'gotmpl', lua = 'lua',
python = 'python', rust = 'rust', javascript = 'javascript',
typescript = 'typescript', typescriptreact = 'tsx', help = 'vimdoc',
vim = 'vim', sh = 'bash', bash = 'bash', markdown = 'markdown',
query = 'query', json = 'json', yaml = 'yaml', toml = 'toml',
html = 'html', css = 'css',
}
vim.api.nvim_create_autocmd('FileType', {
pattern = vim.tbl_keys(ft_map),
callback = function(args)
local lang = ft_map[vim.bo[args.buf].filetype]
if not lang then return end
pcall(vim.treesitter.start, args.buf, lang)
vim.bo[args.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
end,
})
vim.keymap.set('n', '<c-space>', function()
vim.cmd('normal! v')
local node = vim.treesitter.get_node()
if node then
local r1, c1, r2, c2 = node:range()
vim.api.nvim_win_set_cursor(0, { r1 + 1, c1 })
vim.cmd('normal! v')
vim.api.nvim_win_set_cursor(0, { r2 + 1, math.max(c2 - 1, 0) })
end
end, { desc = 'TS node select' })
end,
},
{
'nvim-treesitter/nvim-treesitter-textobjects',
branch = 'main',
dependencies = { 'nvim-treesitter/nvim-treesitter' },
event = 'VeryLazy',
config = function()
local select = require('nvim-treesitter-textobjects.select').select_textobject
local move = require('nvim-treesitter-textobjects.move')
local swap = require('nvim-treesitter-textobjects.swap')
local sel = {
aa = '@parameter.outer', ia = '@parameter.inner',
af = '@function.outer', ['if'] = '@function.inner',
ac = '@class.outer', ic = '@class.inner',
}
for k, q in pairs(sel) do
for _, m in ipairs({ 'x', 'o' }) do
vim.keymap.set(m, k, function() select(q, 'textobjects') end, { desc = 'TS ' .. q })
end
end
local goto_map = {
{ ']m', 'goto_next_start', '@function.outer' },
{ ']]', 'goto_next_start', '@class.outer' },
{ ']M', 'goto_next_end', '@function.outer' },
{ '][', 'goto_next_end', '@class.outer' },
{ '[m', 'goto_previous_start', '@function.outer' },
{ '[[', 'goto_previous_start', '@class.outer' },
{ '[M', 'goto_previous_end', '@function.outer' },
{ '[]', 'goto_previous_end', '@class.outer' },
}
for _, m in ipairs(goto_map) do
vim.keymap.set({ 'n', 'x', 'o' }, m[1], function() move[m[2]](m[3], 'textobjects') end, { desc = 'TS ' .. m[2] .. ' ' .. m[3] })
end
vim.keymap.set('n', '<leader>a', function() swap.swap_next('@parameter.inner') end, { desc = 'TS swap next param' })
vim.keymap.set('n', '<leader>A', function() swap.swap_previous('@parameter.inner') end, { desc = 'TS swap prev param' })
end,
},
}
@@ -0,0 +1,22 @@
-- Owns <C-h/j/k/l> only inside tmux; herdr-splits.nvim owns them in herdr.
return {
"christoomey/vim-tmux-navigator",
cond = vim.env.TMUX ~= nil and vim.env.TMUX ~= "",
cmd = {
"TmuxNavigateLeft",
"TmuxNavigateDown",
"TmuxNavigateUp",
"TmuxNavigateRight",
"TmuxNavigatePrevious",
},
init = function()
vim.g.tmux_navigator_no_mappings = 1
end,
keys = {
{ "<c-h>", "<cmd><C-U>TmuxNavigateLeft<cr>" },
{ "<c-j>", "<cmd><C-U>TmuxNavigateDown<cr>" },
{ "<c-k>", "<cmd><C-U>TmuxNavigateUp<cr>" },
{ "<c-l>", "<cmd><C-U>TmuxNavigateRight<cr>" },
{ "<c-\\>", "<cmd><C-U>TmuxNavigatePrevious<cr>" },
},
}
+40
View File
@@ -0,0 +1,40 @@
vim.opt.shell = "/bin/zsh"
vim.g.mapleader = " "
vim.o.hlsearch = false
vim.wo.number = true
vim.wo.relativenumber = true
vim.wo.signcolumn = "auto"
-- Enable mouse mode
vim.o.mouse = "a"
vim.o.tabstop = 4
vim.o.softtabstop = 4
vim.o.shiftwidth = 4
vim.o.expandtab = true
vim.o.smartindent = true
-- Sync clipboard between OS and Neovim.
vim.o.clipboard = "unnamedplus"
-- Enable break indent
vim.o.breakindent = false
vim.o.wrap = true
-- Save undo history
vim.o.undofile = true
-- Case-insensitive searching UNLESS \C or capital in search
vim.o.ignorecase = true
vim.o.smartcase = true
vim.o.scrolloff = 8
-- Decrease update time
vim.o.updatetime = 250
vim.o.timeoutlen = 300
-- Set completeopt to have a better completion experience
vim.o.completeopt = "menuone,noselect"
vim.o.termguicolors = true
+2
View File
@@ -0,0 +1,2 @@
require('catppuccin').setup()
vim.cmd.colorscheme "catppuccin"
+37
View File
@@ -0,0 +1,37 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json
version: 3
final_space: true
blocks:
- type: prompt
alignment: left
segments:
- type: path
style: plain
foreground: blue
background: transparent
template: "{{ .Path }}"
properties:
style: folder
- type: git
style: plain
foreground: green
background: transparent
template: " {{ .HEAD }}{{ if .Working.Changed }}*{{ end }}"
properties:
fetch_status: true
- type: text
style: plain
foreground_templates:
- "{{if gt .Code 0}}red{{end}}"
- "{{if eq .Code 0}}white{{end}}"
background: transparent
template: " "
transient_prompt:
template: " "
background: transparent
foreground_templates:
- "{{if gt .Code 0}}red{{end}}"
- "{{if eq .Code 0}}white{{end}}"
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
# Norwegian Handy instance (whisper-large-v3, language pinned to "no").
# Runs on a private D-Bus session bus so the tauri single-instance lock
# (D-Bus name com.pais.handy) doesn't collide with the main English
# instance, and with its own XDG_DATA_HOME for a separate settings store.
# Models are shared via ~/.cache/huggingface — no duplicate downloads.
#
# Usage: handy-no start | toggle | gui | cancel
set -euo pipefail
export XDG_DATA_HOME="$HOME/.local/share/handy-no"
export BUSFILE="$XDG_RUNTIME_DIR/handy-no.bus"
case "${1:-start}" in
start)
# First run on a new machine: seed this instance's settings from the
# main (English) store and apply the Norwegian overrides. The live
# store stays out of git — Handy rewrites it at runtime and it can
# hold API keys.
NO_STORE="$XDG_DATA_HOME/com.pais.handy/settings_store.json"
EN_STORE="$HOME/.local/share/com.pais.handy/settings_store.json"
if [ ! -f "$NO_STORE" ] && [ -f "$EN_STORE" ]; then
mkdir -p "${NO_STORE%/*}"
python3 - "$EN_STORE" "$NO_STORE" <<'PY'
import json, sys
en, out = sys.argv[1:3]
d = json.load(open(en))
s = d["settings"]
s["selected_model"] = "handy-computer/whisper-large-v3-gguf/whisper-large-v3-Q5_K_M.gguf"
s["selected_language"] = "no" # pinned: auto-detect mistakes Norwegian for Swedish
s["show_tray_icon"] = False
s["autostart_enabled"] = False # hyprland autostarts this instance
s["onboarding_completed"] = True
s["post_process_api_keys"] = {k: "" for k in s.get("post_process_api_keys", {})}
json.dump(d, open(out, "w"), indent=2)
PY
fi
# Publish the private bus address so toggle/gui/cancel can reach
# this instance through the single-instance forwarder.
exec dbus-run-session -- sh -c \
'echo "$DBUS_SESSION_BUS_ADDRESS" > "$BUSFILE"; exec handy --start-hidden --no-tray'
;;
toggle | gui | cancel)
DBUS_SESSION_BUS_ADDRESS="$(cat "$BUSFILE")"
export DBUS_SESSION_BUS_ADDRESS
case "$1" in
toggle) exec handy --toggle-transcription ;;
cancel) exec handy --cancel ;;
gui) exec handy ;;
esac
;;
*)
echo "usage: handy-no {start|toggle|gui|cancel}" >&2
exit 2
;;
esac
+54
View File
@@ -0,0 +1,54 @@
set -g default-terminal "tmux-256color"
# Set prefix to C-a
set -g prefix C-a
unbind C-b
bind-key C-a send-prefix
# Change binding for splitting terminal
unbind %
bind C-h split-window -v
unbind '"'
bind C-v split-window -h
# Refresh config
unbind r
bind r source-file ~/.tmux.conf
bind c new-window -c '#{pane_current_path}'
# Resize panes
bind -r j resize-pane -D 5
bind -r k resize-pane -U 5
bind -r l resize-pane -R 5
bind -r h resize-pane -L 5
bind -r m resize-pane -Z
set -g mouse on
set-option -g focus-events on
set-option -g status-position top
# Vin movement for copy
set-window-option -g mode-keys vi
bind-key -T copy-mode-vi 'v' send -X begin-selection # start selecting text with "v"
bind-key -T copy-mode-vi 'y' send -X copy-selection # copy text with "y"
unbind -T copy-mode-vi MouseDragEnd1Pane # don't exit copy mode after dragging with mouse
# tpm plugin
# Rememeber to install tpm on the system!
set -g @plugin 'tmux-plugins/tpm'
# list of tmux plugins
set -g @plugin 'christoomey/vim-tmux-navigator' # for navigating panes and vim/nvim with Ctrl-hjkl
set -g @plugin 'jimeh/tmux-themepack' # to configure tmux theme
set -g @plugin 'tmux-plugins/tmux-resurrect' # persist tmux sessions after computer restart
set -g @plugin 'tmux-plugins/tmux-continuum' # automatically saves sessions for you every 15 minutes
set -g @themepack 'powerline/default/grey' # use this theme for tmux
set -g @resurrect-capture-pane-contents 'on' # allow tmux-ressurect to capture pane contents
set -g @continuum-restore 'on' # enable tmux-continuum functionality
# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'
View File
View File
+2
View File
@@ -0,0 +1,2 @@
[mgr]
show_hidden = true
+4
View File
@@ -0,0 +1,4 @@
# Yazi
CLI file manager
[Configuration docs](https://yazi-rs.github.io/docs/configuration/overview)
+1
View File
@@ -0,0 +1 @@
ANTHROPIC_API_KEY=
+119
View File
@@ -0,0 +1,119 @@
# Set vim mode
bindkey -v
# Check for Homebrew and set it up
if [[ -f "/opt/homebrew/bin/brew" ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -f "/usr/local/bin/brew" ]]; then
eval "$(/usr/local/bin/brew shellenv)"
elif [[ -f "/home/linuxbrew/.linuxbrew/bin/brew" ]]; then
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
else
echo "Homebrew not installed!"
fi
if uwsm check may-start; then
exec uwsm start hyprland.desktop
fi
# Set the directory we want to store zinit and plugins
ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git"
# Download Zinit, if it's not there yet
if [ ! -d "$ZINIT_HOME" ]; then
mkdir -p "$(dirname $ZINIT_HOME)"
git clone https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME"
fi
# Load secrets
[ -f "$HOME/.env" ] && source "$HOME/.env"
# Source/Load zinit
source "${ZINIT_HOME}/zinit.zsh"
# Add zsh plugins
zinit light zsh-users/zsh-syntax-highlighting
zinit light zsh-users/zsh-completions
zinit light zsh-users/zsh-autosuggestions
zinit light Aloxaf/fzf-tab
# Add in snippets
zinit snippet OMZP::git
zinit snippet OMZP::sudo
# Load completions
autoload -Uz compinit && compinit
zinit cdreplay -q
# History
HISTSIZE=5000
HISTFILE="$HOME/.zsh_history"
SAVEHIST=$HISTSIZE
HISTDUP=erase
setopt appendhistory
setopt sharehistory
setopt hist_ignore_space
setopt hist_ignore_all_dups
setopt hist_save_no_dups
setopt hist_ignore_dups
setopt hist_find_no_dups
# Completion styling
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
zstyle ':completion:*' menu no
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'ls --color $realpath'
zstyle ':fzf-tab:complete:__zoxide_z:*' fzf-preview 'ls --color $realpath'
# Aliases
alias ls='ls --color'
alias vim='nvim'
alias v='nvim'
alias c='clear'
alias air='$HOME/go/bin/air'
alias lg="lazygit"
alias claude="$HOME/.local/bin/claude"
# Oh-my-posh integration
eval "$(oh-my-posh init zsh --config $HOME/.ohmyposhconfig.yaml)"
# Shell integrations
eval "$(fzf --zsh)"
eval "$(zoxide init zsh)"
# Yazi wrapper
function y() {
local tmp="$(mktemp -t "yazi-cwd.XXXXXX")" cwd
yazi "$@" --cwd-file="$tmp"
if cwd="$(command cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
builtin cd -- "$cwd"
fi
rm -f -- "$tmp"
}
# Environment variables
export EDITOR=nvim
export KEYTIMEOUT=1 # Faster vim mode switching. Default 40ms
export XDG_PROJECTS_DIR='$HOME/projects'
# Path
export PATH=$PATH:$HOME/.local/bin
export PATH=$PATH:$(go env GOROOT)/bin
export PATH=$PATH:$(go env GOPATH)/bin
export PATH=$PATH:$HOME/sdks/flutter/bin
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
# opencode
export PATH=$HOME/.opencode/bin:$PATH
fpath=(~/.local/share/zsh/site-functions $fpath)
# bun completions
[ -s "$HOME/.bun/_bun" ] && source "$HOME/.bun/_bun"
# bun
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"