80 Commits
Author SHA1 Message Date
DarthMooMancer 72951f7327 chore: fixed create_file to take filetype over asking for language each
time as 97% of the time people (I) will want to make the same filetype
instead
2026-10-28 10:30:06 -04:00
DarthMooMancer 4765da0539 chore: cleaning deprecated code 2026-10-27 17:03:32 -04:00
DarthMooMancer 9f4649b5d2 chore: combined (actions/utils.lua).create with (actions/init.lua).create_project 2026-10-27 16:53:43 -04:00
DarthMooMancer e8c55ec18f feat: added java and refactored how context is utilized 2026-10-27 14:35:19 -04:00
DarthMooMancer fcde51bc05 chore: redundancy removing and pushing before local changes 2026-10-27 00:14:09 -04:00
DarthMooMancer 9eefdb6166 refactor: fully moved attach to configs for compression
Removed the entire folder of attach because there was mostly boilerplate
instead of language specific code. It was redundant and just for testing
to have concept of what I wanted
2026-10-26 23:45:04 -04:00
DarthMooMancer 3046a3ce36 refactor: continuation of compressing languages to be agnostic 2026-10-26 21:11:55 -04:00
DarthMooMancer 5eaa7d10a7 refactor: realized I was heavily unoptimized.
Each language had the same boilerplate code to create new projects and
new files with minor differences between each language making them
difficult to edit and navigate.
2026-10-26 14:13:33 -04:00
DarthMooMancer 774f14809d RENAME: Changed vern.nvim to vern-nvim and moved vern to vern-nvim 2026-10-26 09:48:33 -04:00
DarthMooMancer 645eeed296 README: updated available languages 2026-10-23 09:32:40 -04:00
DarthMooMancer 4bf705df03 CHORE: Bug fixed c and cpp files and fixed their templates. Bug #3 is
also done
2026-10-23 09:30:37 -04:00
DarthMooMancer 1c4a61ce7f CHORE: Fixed bug #4 by looping dirs and creating directories before
other loops in creation.
LANG: Added CPP and bugfixed c to use c code and not python
2026-10-23 08:25:21 -04:00
DarthMooMancer b6d46a0cef Chore: moved similar functions to a utils for actions so they dont
repeat and copy costantly. Going to have to think of a better way that
consolidates it all as a lot of it overlaps
2026-10-22 14:36:19 -04:00
DarthMooMancer 685a711644 REFACTOR: Annotations for autocompletion, reworked how projects are made
and handled, wrote the c file replacing the copied python code.
2026-10-22 04:29:52 -04:00
DarthMooMancer 3bb97d833b REFACTOR: Completely changed how project creation is done so I can make
other languages easier and hopefully faster
2026-10-22 00:19:19 -04:00
DarthMooMancer df760783ba CHORE: cleaning up 2026-10-20 22:40:38 -04:00
DarthMooMancer 57e8eb0248 PYTHON: added venv creation 2026-10-20 17:42:25 -04:00
DarthMooMancer 0f542d56ef PYTHON: Project setup fixed and working, just need to add providers 2026-10-19 20:24:45 -04:00
DarthMooMancer e2864159a8 CHORE: officially renamed files to be deprecated and also made making
templates simpler
2026-10-19 14:29:51 -04:00
DarthMooMancer 380f295c93 FEAT: adding create_project 2026-10-19 11:59:24 -04:00
DarthMooMancer 06eb74e13f REFACTOR: Cleaning up project and removing more deprecated code 2026-10-16 10:38:06 -04:00
DarthMooMancer 98bd619cfa REFACTOR: Merged templates into a per language file, deleted init.lua as
it was just a middle man and wasnt needed (in fact it is better without
it)
FT: Changes to python
2026-10-15 23:32:26 -04:00
DarthMooMancer 6593db3829 CHORE: Updated License and cleaned up repo 2026-10-15 09:59:14 -04:00
DarthMooMancer 4bcac5d09b REFACTOR: I spent all day on it but I am heavily refactoring the API and
organization because it was terrible before and hard to maintain. Now it
should be much easier and there is still of a design decisions to figure
out
2026-10-15 02:07:14 -04:00
Andrew Haynes 2b30e36fad major changes to try and fix a bunch of random bugs 2026-08-03 16:03:08 -04:00
Andrew Haynes 8d41141e9a configs should update properly 2026-03-31 18:38:18 -04:00
Andrew Haynes 919d141c6a LANG: Javascript finally fixed...hopefully 2026-03-30 00:17:21 -04:00
Andrew Haynes 89bf0333c4 ? 2026-03-30 00:16:04 -04:00
Andrew Haynes 9210dff133 ? 2026-03-30 00:12:17 -04:00
Andrew Haynes 262e377873 ? 2026-03-30 00:09:40 -04:00
Andrew Haynes 5cec285828 ? 2026-03-30 00:08:30 -04:00
Andrew Haynes 22215cccda ? 2026-03-30 00:04:53 -04:00
Andrew Haynes 2ca6c62cd8 LANG: javascript - lets see if this works 2026-03-29 00:47:50 -04:00
Andrew Haynes d99dc30dcd LANG: added javascript init 2026-03-29 00:27:54 -04:00
Andrew Haynes 62015919dd plz 2026-03-19 14:01:42 -04:00
Andrew Haynes e0cbc48cc0 c/c++ changes 2026-03-07 13:45:34 -05:00
Gentoo 15718d57fa .clang-format for c/c++ 2026-03-06 03:55:26 -05:00
DarthMooMancer c907211784 Update README.md 2025-12-10 17:58:20 +00:00
DarthMooMancer 053c567618 cleaning 2025-12-01 01:08:04 -05:00
DarthMooMancer faf87f3643 Update README.md 2025-12-01 06:07:13 +00:00
DarthMooMancer 1df75ee212 removing github 2025-12-01 00:40:00 -05:00
DarthMooMancer ce406bfad3 c++ 2025-11-13 02:24:38 -05:00
DarthMooMancer 0dec930412 c++ 2025-11-13 02:23:38 -05:00
DarthMooMancer d7b949d9f9 ui changes 2025-10-30 23:03:07 -04:00
DarthMooMancer bf56094156 fixes 2025-10-30 22:33:34 -04:00
DarthMooMancer 1a450ff79a wip 2025-10-26 21:04:05 -04:00
DarthMooMancer 76791fd7c1 wip 2025-10-26 21:02:59 -04:00
DarthMooMancer 45fcdf78be wip 2025-10-26 21:01:40 -04:00
DarthMooMancer d1cb867cf8 c++ fix 2025-10-03 09:23:57 -04:00
Andrew Haynes 5bf74a6639 Update templates.lua 2025-09-19 13:47:27 -04:00
dmm 2b440c2935 Update issue templates 2025-09-07 15:12:33 +00:00
dmm 5420c54d9a Create CONTRIBUTING.md 2025-09-07 15:08:25 +00:00
dmm ad97a31a31 Create CODE_OF_CONDUCT.md 2025-09-07 15:06:21 +00:00
DarthMooMancer 0a8495fe79 fix 2025-09-04 21:13:24 -04:00
DarthMooMancer a246f2ab03 Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-09-04 21:07:31 -04:00
DarthMooMancer 5765c8ea19 fix: c/c++ had compile commands linked unnecassarily 2025-09-04 21:07:27 -04:00
dmm e701aa1feb Update README.md 2025-09-04 20:52:09 -04:00
DarthMooMancer bc825895ac fix: changed formatting and defaults for c/c++ 2025-09-01 00:36:35 -04:00
DarthMooMancer 0cc4374865 wip 2025-08-22 19:30:24 -04:00
DarthMooMancer 66ae61f2c9 fix(ui): closes ui when making projects and files 2025-07-20 02:27:24 -04:00
DarthMooMancer cf84fe2080 feat(plugin.Polydev): Added for automatically starting the plugin so opts or require are not necessary 2025-06-29 16:09:45 -04:00
DarthMooMancer beddb26757 chore(presets): formatting presets to be nicer 2025-06-21 03:50:26 -04:00
DarthMooMancer df473b1d33 fix(ui): forgot to add keybinds to new ui 2025-06-21 03:35:11 -04:00
DarthMooMancer e3fdeb53b3 fix(README): readme no longer has warning about ui as I have it fixed 2025-06-21 02:56:42 -04:00
DarthMooMancer 8c2498d00f feat(ui): removed nui dependency and now have tabbed ui for current project and recent folders and files
chore(all): just cleaned up and removed some redundant code
2025-06-21 02:56:01 -04:00
DarthMooMancer 69c648c4f4 Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-05-27 13:50:55 -04:00
DarthMooMancer 60e5d9ea2f refactor(ui): removed the preview and search popups. Refactored project specific code be faster and more maintained 2025-05-27 13:50:50 -04:00
DarthMooMancer 109489a2aa Update README.md 2025-05-27 13:49:21 -04:00
DarthMooMancer 6937318b2e Update README.md 2025-05-27 13:46:26 -04:00
DarthMooMancer 23bc6c2bfc Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-05-22 08:12:32 -04:00
DarthMooMancer 38284658dd chore: removing redundant code 2025-05-22 08:12:27 -04:00
DarthMooMancer 759278b9ff Update README.md 2025-05-20 14:37:42 -04:00
DarthMooMancer 14b302151b fix(utils): fixed bottom split and added sizing for splits 2025-05-20 09:27:04 -04:00
DarthMooMancer e6c3353b51 feat(utils): added ability to have floating or split windows and anchors of where each are
fix(ui): also changed deprecated features to use newer features by
neovim
2025-05-17 18:33:55 -04:00
DarthMooMancer eea8def35c docs(appearance): update 2025-05-16 13:10:57 -04:00
DarthMooMancer d5fadfa55e docs(appearance): added appearance tab 2025-05-16 12:59:53 -04:00
DarthMooMancer 7e047478d5 fix(deprecated): replacing deprecated code throughout project
rework: moved load_language_module to languages as it makes more sense
2025-05-16 10:53:34 -04:00
DarthMooMancer 9eb38ba06e docs(mkdocs.yml): removed language specific docs 2025-05-16 09:40:25 -04:00
DarthMooMancer 85f05563ce docs(languages): added gitignore to each language fixing https://github.com/DarthMooMancer/Polydev/issues/6 2025-05-16 09:37:54 -04:00
DarthMooMancer 7646aa3295 fix(docs): forgot to push mkdocs.yml 2025-05-16 01:04:46 -04:00
45 changed files with 1957 additions and 1797 deletions
-22
View File
@@ -1,22 +0,0 @@
name: ci
on:
push:
branches:
- master
- main
permissions:
contents: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.x
- uses: actions/cache@v3
with:
key: ${{ github.ref }}
path: .cache
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force
+17 -197
View File
@@ -1,201 +1,21 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
MIT License
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Copyright (c) 2026 Andrew Haynes
1. Definitions.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2025 DarthMooMancer
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+14 -20
View File
@@ -1,42 +1,39 @@
<h1 align="center">Polydev</h1>
<h1 align="center">Vern.nvim</h1>
<p align="center"><em>A multi-language project managing plugin for file creation, building, and running code—all within neovim. Whether you're coding in Java, Python, Lua, Rust, or more, Polydev provides seamless integration to boost your productivity inside Neovim.</em></p>
<p align="center"><em>Vern.nvim or Vernacular.nvim is a multi lingual project manager. It creates new projects and files from templates, builds and runs code and can run language specific functions within Neovim</em></p>
<p align="center">
<img src="https://img.shields.io/badge/Lua-1e90ff?style=for-the-badge&logo=lua&logoColor=white" />
<img src="https://img.shields.io/badge/Neovim-0.10%2B-32c48d?style=for-the-badge&logo=neovim&logoColor=white" />
<img src="https://img.shields.io/github/stars/DarthMooMancer/Polydev?style=for-the-badge&logo=github" />
<img src="https://img.shields.io/badge/License-Apache-yellow.svg?style=for-the-badge" />
<img src="https://img.shields.io/badge/Docs-Available-blue?style=for-the-badge&logo=readthedocs&logoColor=white" />
<img src="https://img.shields.io/badge/License-MIT-yellow.svg?style=for-the-badge" />
<!-- <img src="https://img.shields.io/badge/Docs-Available-blue?style=for-the-badge&logo=readthedocs&logoColor=white" /> -->
</p>
<p align="center">
<img src="https://github.com/user-attachments/assets/c8e84056-5080-4ec3-ba15-30be61faaf68" alt="Polydev Preview" width="720"/>
</p>
NOTE: The plugin may not work well with lazy or any other package manager other than vim.pack. I dont understand enough about nvim api and lua to handle these other things right now
## Features
* Create and manage projects directly from Neovim
* Create projects directly from Neovim
* Generate new files quickly
* Build your code with customizable build systems
* Run programs without leaving the editor
* Integrated terminal for flexible command execution
* Lightweight, fast project manager UI
* Minimal configuration with extensibility in mind
> 📚 [View the full documentation](https://darthmoomancer.github.io/Polydev/) for setup, configuration, and usage details.
> 📚 [View the full documentation](https://git.moomancer.xyz/DarthMooMancer/vern-nvim.nvim/wiki/Home$0) for setup, configuration, and usage details.
## Supported Languages
Polydev currently supports the following languages:
Vern.nvim currently supports the following languages:
* Java
* Python
* C / C++
* Lua
* Rust
* HTML
* Java
<!-- * Rust -->
<!-- * HTML -->
Additional language support is planned for future releases.
@@ -46,9 +43,6 @@ Additional language support is planned for future releases.
Current focus:
* **Refactoring and internal cleanup.**
Feature additions will resume after this phase.
## Contributing
Contributions are welcome and appreciated.
@@ -57,4 +51,4 @@ Contributions are welcome and appreciated.
* Submit a pull request if you'd like to contribute directly.
If you have an idea or use case you'd like to see supported, let’s discuss it.
Your feedback and contributions are key to making Polydev even better! Thank you for being part of the journey. 🙏
Your feedback and contributions are key to making Vern.nvim even better! Thank you for being part of the journey. 🙏
-18
View File
@@ -1,18 +0,0 @@
#!/usr/bin/env bash
DIR="$(pwd)"
while [[ ! -f "$DIR/CMakeLists.txt" && \
! -f "$DIR/package.json" && \
! -f "$DIR/venv" && \
! -d "$DIR/.git" && \
"$DIR" != "/" ]]; do
DIR="$(dirname "$DIR")"
done
if [[ "$DIR" == "/" ]]; then
echo "❌ Project root not found."
exit 1
fi
echo "$DIR"
-70
View File
@@ -1,70 +0,0 @@
<p align="center"><em>A multi-language project managing plugin for file creation, building, and running code—all within neovim. Whether you're coding in Java, Python, Lua, Rust, or more, Polydev provides seamless integration to boost your productivity inside Neovim.</em></p>
<p align="center">
<img src="https://img.shields.io/badge/Lua-1e90ff?style=for-the-badge&logo=lua&logoColor=white" />
<img src="https://img.shields.io/badge/Neovim-0.10%2B-32c48d?style=for-the-badge&logo=neovim&logoColor=white" />
<img src="https://img.shields.io/github/stars/DarthMooMancer/Polydev?style=for-the-badge&logo=github" />
<img src="https://img.shields.io/badge/License-Apache-yellow.svg?style=for-the-badge" />
</p>
<p align="center">
<img src="https://github.com/user-attachments/assets/c8e84056-5080-4ec3-ba15-30be61faaf68" alt="Polydev Preview" width="720"/>
</p>
## **Why Polydev**?
Working across multiple languages often means repetitive setup and constant context switching. Polydev eliminates this friction by offering:
* Project templates per language
* Custom keybindings for essential actions
* Floating terminal integration
* Automated file and folder generation
* A plugin-first design for easy extensibility
## **Core Features**
* **Language Profiles**
Define settings per language including `project_root`, keymaps, and build commands.
* **Floating Terminals**
Run build, and run commands in a clean, isolated terminal window inside Neovim.
* **Scaffolding**
Quickly generate boilerplate and structured directories for new projects.
* **Custom Keybinds**
Map actions like `Run`, `PipInstall`, `Open Manager`, `etc` to your preferred keys.
* **Pluggable Design**
Easily extend functionality with custom language presets and commands.
## **Who It's For**
* Developers who work in multiple languages
* Neovim plugin authors or power users
* Anyone who wants a faster, more unified project workflow
## **Design Goals**
* **Consistency**
Offer a predictable workflow across languages and tools.
* **Extensibility**
Support custom configurations, commands, and language integrations.
* **Simplicity**
Reduce boilerplate, context switching, and friction.
## **Real-World Example**
If you switch often between Rust, Lua, and Python:
1. Polydev sets up your project layout automatically.
2. Creates boilerplate like `main.rs`, `init.lua`, or `main.py`.
3. Maps commands to keys (e.g. `<leader>pr` to run, `<leader>po` to open the manager).
4. Opens a floating terminal with build or run output — no extra configuration required.
-43
View File
@@ -1,43 +0,0 @@
## **Lazy.nvim**
```lua
return {
"DarthMooMancer/Polydev",
dependencies = {
"MunifTanjim/nui.nvim"
},
opts = {}, -- Setup is later on
}
```
---
## **Mini.deps**
```lua
MiniDeps.add({
source = "DarthMooMancer/Polydev"
depends = {
"MunifTanjim/nui.nvim"
}
})
require("Polydev").setup({})
```
---
## **Packer.nvim**
```lua
use({
"DarthMooMancer/Polydev",
requires = {
"MunifTanjim/nui.nvim"
},
})
require("Polydev").setup({})
```
---
-150
View File
@@ -1,150 +0,0 @@
## Java
#### Structure Reference
| Directory/File Path | Description |
|----------------------------|------------------------------------------------------|
| `src/` | Contains the source code files, including `Main.java` |
| `build/` | Contains compiled `.class` files |
| `Main.java` | The main entry point of your Java project |
#### Project Layout
```md
Projects/
└── Java/
└── Project_Name/
├── src/
│ └── Main.java
└── build/
└── *.class
```
---
## C
#### Structure Reference
| Directory/File Path | Description |
|----------------------------|------------------------------------------------------|
| `CMakeLists.txt` | Configuration file for your project build |
| `src/` | Folder containing source files for the project |
| `main.c` | Main C file for the project |
| `*.c` | Additional C source files |
| `build/` | Folder where the build artifacts will be generated |
| `include/` | Folder for header files |
| `*.h` | C header files |
#### Project Layout
```md
Projects/
└── C/
└── Project_Name/
├── CMakeLists.txt
├── src/
│ ├── main.c
│ └── *.c
├── build/
│ └── <CMAKE_FILES>
│ └── <main-executable>
└── include/
└── *.h
```
---
## C++
#### Structure Reference
| Directory/File Path | Description |
|----------------------------|------------------------------------------------------|
| `CMakeLists.txt` | Configuration file for your project build |
| `src/` | Folder containing source files for the project |
| `main.cpp` | Main Cpp file for the project |
| `*.cpp` | Additional Cpp source files |
| `build/` | Folder where the build artifacts will be generated |
| `include/` | Folder for header files |
| `*.hpp` | Cpp header files |
#### Project Layout
```md
Projects/
└── Cpp/
└── Project_Name/
├── CMakeLists.txt
├── src/
│ ├── main.cpp
│ └── *.cpp
├── build/
│ └── <CMAKE_FILES>
│ └── <main-executable>
└── include/
└── *.hpp
```
---
## Lua
#### Structure Reference
| Directory/File Path | Description |
|----------------------------|-----------------------------------------------------|
| `lua/<Project_name>` | Directory containing the main Lua project files |
| `lua/<Project_name>/init.lua` | The main entry point for your Lua project |
#### Project Layout
```md
Projects/
└── Lua/
└── Project_Name/
└── lua/
└── Project_name/
└── init.lua -- Main Lua file
```
---
## Python
- **Automatic Virtual Environment Creation**: Each Python project automatically sets up and uses a new virtual environment. You don’t need to worry about environment management. Just install your dependencies with `pip` as needed.
- **Dependency Management with Pip**: Need to install Python modules? Simply type the name of the module in the terminal, and Polydev will take care of the installation using `pip`. You can even update `pip` if required, ensuring smooth installation.
#### Structure Reference
| Directory/File Path | Description |
|----------------------------|------------------------------------------------------|
| `requirements.txt` | File for listing project dependencies |
| `setup.py` | Python project setup file |
| `tests/` | Folder containing test files |
| `venv/` | Virtual environment folder |
| `main.py` | Main Python file for your project |
#### Project Layout
```md
Projects/
└── Python/
└── Project_Name/
├── main.py
├── requirements.txt
├── setup.py
├── tests/
└── venv/
```
---
## Html
Nothing here yet! Html is supported however! Will do later
## Rust
Nothing here yet! Rust is supported however! Will do later
-127
View File
@@ -1,127 +0,0 @@
## **Project Manager**
> Note: The project manager closely follows the netrw keybinds and allows for project management all in one spot
| Binding | Description |
|------------------|-----------------|
| **ENTER** | `Open file / Enter directory` |
| **DELETE** | `Go to parent directory` |
| **/** | `Filter (fuzzy search)` |
| **a** | `Create new folder` |
| **%** | `Create new file` |
| **x** | `Create new auxilary file (ex. headers)` |
| **d** | `Create new project` |
| **R** | `Rename file/folder` |
| **D** | `Delete file/folder` |
| **ESC** | `Quit popup` |
> **WARNING**: Do not copy the defaults. Only change what you need for your workflow!
## **Project Root**
```lua
-- Automatically creates a project root if not already made.
-- Stores all projects in this root
-- Global --
globals = {
project_root = "~/Projects"
}
-- Lua --
lua = {
project_root = "~/{global_root}/Lua"
}
-- Html --
html = {
project_root = "~/{global_root}/Html"
}
-- Rust --
rust = {
project_root = "~/{global_root}/Rust"
}
-- Java --
java = {
project_root = "~/{global_root}/Java"
}
-- Python --
python = {
project_root = "~/{global_root}/Python"
}
-- C --
c = {
project_root = "~/{global_root}/C"
}
-- C++ --
cpp = {
project_root = "~/{global_root}/CPP"
}
```
## **Keybinds**
```lua
-- globals --
globals = {
keybinds = {
["<leader>po"] = "PolydevManager",
}
}
-- rust --
rust = {
keybinds = {
["<leader>pr"] = "RustRun",
}
}
-- java --
java = {
keybinds = {
["<leader>pr"] = "JavaRun",
}
}
-- python --
python = {
keybinds = {
["<leader>pr"] = "PythonRun",
["<leader>pb"] = "PythonPip",
}
}
-- lua --
lua = {
keybinds = {
["<leader>pr"] = "LuaRun",
}
}
-- c --
c = {
keybinds = {
["<leader>pr"] = "CRun",
}
}
-- cpp --
cpp = {
keybinds = {
["<leader>pr"] = "CppRun",
}
}
```
## **Terminal Configuration**
```lua
-- In Neovim 0.11+, numbers don't work so they will be reimplemented later
terminal = {
preset = nil, -- also try : ("right", "corner")
border = true
}
```
-80
View File
@@ -1,80 +0,0 @@
local M = {}
M.defaults = {
globals = {
project_root = "~/Projects",
keybinds = {
["<leader>po"] = "PolydevManager",
},
},
terminal = {
preset = nil,
border = {
enabled = true,
type = "rounded",
},
},
}
local function default_languages(project_root)
return {
rust = {
project_root = project_root .. "/Rust",
keybinds = {
["<leader>pr"] = "RustRun",
},
},
java = {
project_root = project_root .. "/Java",
keybinds = {
["<leader>pr"] = "JavaRun",
},
},
lua = {
project_root = project_root .. "/Lua",
keybinds = {
["<leader>pr"] = "LuaRun",
},
},
c = {
project_root = project_root .. "/C",
keybinds = {
["<leader>pr"] = "CRun",
},
},
cpp = {
project_root = project_root .. "/CPP",
keybinds = {
["<leader>pr"] = "CppRun",
},
},
html = {
project_root = project_root .. "/Html",
},
}
end
M.user_config = {}
---@param user_opts table
function M.setup(user_opts)
-- First merge global and terminal
M.user_config = vim.tbl_deep_extend("force", {}, M.defaults, user_opts or {})
-- Now use the final resolved project_root from user_config
local root = M.user_config.globals.project_root
local langs = default_languages(root)
-- Inject languages into the config, respecting user overrides
for lang, conf in pairs(langs) do
M.user_config[lang] = vim.tbl_deep_extend("force", conf, M.user_config[lang] or {})
end
end
---@param lang string
---@return table
function M.get(lang)
return M.user_config[lang] or {}
end
return M
-29
View File
@@ -1,29 +0,0 @@
local M = {}
function M.setup(opts)
local config = require("Polydev.configs")
local ui = require("Polydev.ui")
config.setup(opts)
require("Polydev.utils").setup(opts)
for lang, user_opts in pairs(opts) do
config.user_config[lang] = vim.tbl_deep_extend("force", config.defaults[lang] or {}, user_opts)
end
vim.api.nvim_create_user_command("PolydevOpen", function() ui.manager(config.get("globals").project_root) end, {})
-- require("Polydev.styles").setup_highlights()
local keys = vim.tbl_deep_extend("force", {}, config.get("globals").keybinds, opts.keybinds or {})
for key, _ in pairs(keys) do
vim.keymap.set("n", key, ":PolydevOpen<CR>")
end
vim.api.nvim_create_autocmd("FileType", {
pattern = "*",
callback = function()
local filetype = vim.bo.filetype
ui.load_language_module(filetype, opts)
end,
})
end
return M
-174
View File
@@ -1,174 +0,0 @@
local utils = require("Polydev.utils")
local configs = require("Polydev.configs")
local M = {}
M.languages = {
java = {
setup = function (self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("java"), user_opts or {})
vim.api.nvim_create_user_command("JavaRun", function() self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":JavaRun<CR>", { silent = true })
end
end,
run = function ()
local root = utils.get_project_root()
local cmd = string.format("javac -d %s %s", root .. "/build", root .. "/src/*.java")
local output = vim.fn.system(cmd)
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
else
utils.terminal({ "java -cp " .. root, "build" .. " Main" })
end
end
},
c = {
setup = function (self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("c"), user_opts or {})
vim.api.nvim_create_user_command("CRun", function () self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":CRun<CR>", { silent = true })
end
end,
run = function ()
local root = utils.get_project_root()
local build_dir = root .. "/build"
local cmd = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
if not success then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
if success then
local run_cmd = "cd '" .. build_dir .. "' && ./" .. utils.get_project_name()
utils.terminal({ run_cmd })
end
end
},
cpp = {
setup = function (self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("cpp"), user_opts or {})
vim.api.nvim_create_user_command("CppRun", function () self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":CppRun<CR>", { silent = true })
end
end,
run = function ()
local root = utils.get_project_root()
local build_dir = root .. "/build"
local cmd = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
if not success then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
if success then
local run_cmd = "cd '" .. build_dir .. "' && ./" .. utils.get_project_name()
utils.terminal({ run_cmd })
end
end
},
html = {
setup = function (user_opts)
vim.tbl_deep_extend("force", {}, configs.get("html"), user_opts or {})
end
},
rust = {
setup = function (self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("rust"), user_opts or {})
vim.api.nvim_create_user_command("RustRun", function () self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":RustRun<CR>", { silent = true })
end
end,
run = function ()
local root = utils.get_project_root()
if not root then return print("Error: Project root not found.") end
local cmd = { "cargo build" }
local output = vim.fn.system(table.concat(cmd))
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
else
utils.terminal({ "cargo run" })
end
end
},
python = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("python"), user_opts or {})
vim.api.nvim_create_user_command("PythonPip", function () self:install_dependency() end, {})
vim.api.nvim_create_user_command("PythonRun", function () self:run() end, {})
for key, command in pairs(opts.keybinds) do
if command == "PythonRun" then
vim.keymap.set("n", key, ":PythonRun<CR>", { silent = true })
end
if command == "PythonPip" then
vim.keymap.set("n", key, ":PythonPip<CR>", { silent = true })
end
end
local root = utils.get_project_root()
if root then
local venv_path = root .. "/venv/bin/activate"
if vim.fn.filereadable(venv_path) == 1 then
vim.env.VIRTUAL_ENV = venv_path
vim.env.PATH = root .. "/venv/bin:" .. vim.env.PATH
end
end
end,
install_dependency = function ()
vim.ui.input({ prompt = "Enter pip module: " }, function(pip_module)
if not pip_module or pip_module == "" then return print("Pip canceled") end
utils.terminal({ "pip install " .. pip_module })
end)
end,
run = function ()
utils.terminal({ "python3 " .. utils.get_project_root(), "main.py" })
end
},
lua = {
setup = function (self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("lua"), user_opts or {})
vim.api.nvim_create_user_command("LuaRun", function () self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":LuaRun<CR>", { silent = true })
end
end,
run = function ()
local init_lua_path = utils.get_project_root() .. "/lua/" .. utils.get_project_name() .. "/init.lua"
if vim.fn.filereadable(init_lua_path) == 1 then
utils.terminal({ "lua " .. init_lua_path })
end
end
},
}
return M
-35
View File
@@ -1,35 +0,0 @@
local M = {}
---@class padding
---@field left_padding integer
---@field right_padding integer
---@field top_padding integer
---@field bottom_padding integer
---@class preset_list
---@field right padding
---@field corner padding
---@type preset_list
local presets = {
right = {
left_padding = 100,
right_padding = 0,
top_padding = 0,
bottom_padding = 0,
},
corner = {
left_padding = 100,
right_padding = 0,
top_padding = 25,
bottom_padding = 0,
}
}
---@param preset string
---@return table|nil
function M.getPresets(preset)
return presets[preset]
end
return M
-23
View File
@@ -1,23 +0,0 @@
local M = {}
function M.setup_highlights()
-- Only set if not already defined by colorscheme
local function define(name, opts)
if vim.fn.hlexists(name) == 0 then
vim.api.nvim_set_hl(0, name, opts)
end
end
define("PolydevNormal", {
fg = vim.api.nvim_get_hl_by_name("NormalFloat", true).foreground,
bg = vim.api.nvim_get_hl_by_name("Normal", true).background
})
define("PolydevBorder", {
fg = vim.api.nvim_get_hl_by_name("Function", true).foreground,
bg = vim.api.nvim_get_hl_by_name("Normal", true).background
})
define("PolydevTitle", { fg = "#89dceb", bold = true })
end
return M
-255
View File
@@ -1,255 +0,0 @@
local utils = require("Polydev.utils")
local M = {}
local function extras(guard, file_type, file_name)
if not file_name then return print("Header file creation canceled") end
local guard_macro = file_name:upper():gsub("[^A-Z0-9]", "_") .. guard
local content = string.format([[
#ifndef %s
#define %s
// Add code here
#endif
]], guard_macro, guard_macro)
utils.write_file({ utils.get_project_root(), "include", file_name .. file_type }, content)
end
M.projects = {
lua = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.mkdir(full_project_root .. "/lua/" .. project_name, "p")
utils.write_file({ full_project_root, "lua", project_name, "init.lua" }, [[
local M = {}
return M
]])
local gitignore = { "" }
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/lua/" .. project_name .. "/init.lua")
end
},
java = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build" }) do vim.fn.mkdir(full_project_root .. path, "p") end
local content = [[
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
]]
local gitignore = {
"build/"
}
utils.init_git(full_project_root, gitignore)
utils.write_file({ full_project_root, "src", "Main.java" }, content)
end
},
python = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.mkdir(full_project_root .. "/include", "p")
utils.write_file({ full_project_root, "main.py" }, [[
def main():
print("Hello, World!")
if __name__ == "__main__":
main()
]])
utils.write_file({ full_project_root, "include/__init__.py" }, "")
utils.write_file({ full_project_root, "requirements.txt" }, "")
utils.write_file({ full_project_root, "setup.py" }, string.format([[
from setuptools import setup, find_packages
setup(
name="%s",
version="0.1.0",
packages=find_packages(),
install_requires=[],
python_requires=">=3.6",
)
]], project_name))
local gitignore = {
"venv/"
}
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/main.py")
local venv_path = full_project_root .. "/venv"
vim.fn.system("python3 -m venv " .. venv_path)
vim.g.python3_host_prog = venv_path .. "/bin/python"
vim.fn.setenv("VIRTUAL_ENV", venv_path)
vim.fn.setenv("PATH", venv_path .. "/bin:" .. vim.fn.getenv("PATH"))
print("Virtual environment activated for " .. project_name)
end
},
c = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build", "/include" }) do vim.fn.mkdir(full_project_root .. path, "p") end
utils.write_file({ full_project_root, "src/main.c" }, [[
#include <stdio.h>
int main() {
printf("%s", "Hello World");
return 0;
}
]])
utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.10)
project(%s)
include_directories(include)
set(SOURCES src/main.c)
add_executable(%s ${SOURCES})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
# find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg
# target_link_libraries(Game PRIVATE SDL3::SDL3)
]], project_name, project_name))
local gitignore = { "build/" }
utils.init_git(full_project_root, gitignore)
vim.fn.system(string.format("cd %s/build && cmake -S .. -B . && cmake --build . && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. && ln -sf compile_commands.json ../compile_commands.json", full_project_root))
vim.cmd("edit " .. full_project_root .. "/src/main.c")
end
},
cpp = {
run = function (project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build", "/include" }) do
vim.fn.mkdir(full_project_root .. path, "p")
end
utils.write_file({ full_project_root, "src/main.cpp" }, [[
#include <iostream>
int main() {
std::cout << "Hello World" << std::endl;
return 0;
}
]])
utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.10)
project(%s)
include_directories(include)
set(SOURCES src/main.cpp)
add_executable(%s ${SOURCES})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
# find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg
# target_link_libraries(Game PRIVATE SDL3::SDL3)
]], project_name, project_name))
local gitignore = { "build/" }
utils.init_git(full_project_root, gitignore)
vim.fn.system(string.format("cd %s/build && cmake -S .. -B . && cmake --build . && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. && ln -sf compile_commands.json ../compile_commands.json", full_project_root))
vim.cmd("edit " .. full_project_root .. "/src/main.cpp")
end
},
rust = {
run = function (project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.system("cargo new " .. full_project_root)
vim.cmd("edit " .. full_project_root .. "/src/main.rs")
end
},
html = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
if vim.fn.isdirectory(full_project_root) == 0 then
vim.fn.mkdir(full_project_root, "p") -- Create directory with parent directories
end
local main_html_content = [[
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>
]]
utils.write_file({ full_project_root, "index.html" }, main_html_content)
end
},
}
M.files = {
lua = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "lua", utils.get_project_name(), file_name .. ".lua"}, "")
end
},
java = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".java" }, string.format([[
public class %s {
// New File
}
]], file_name))
end
},
python = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "include", file_name .. ".py" }, "")
end
},
c = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".c" }, "")
end
},
cpp = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".cpp" }, "")
end
},
rust = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".rs" }, "")
end
},
html = {
run = function (file_name)
utils.write_file({ ".", file_name .. ".html" }, string.format([[
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>
]]))
end
}
}
M.extras = {
run = function (lang, file_name)
if lang == "c" then
extras("_H", ".h", file_name)
print("Successful creation of " .. file_name .. ".h")
end
if lang == "cpp" then
extras("_HPP", ".hpp", file_name)
print("Successful creation of " .. file_name .. ".hpp")
end
end
}
return M
-404
View File
@@ -1,404 +0,0 @@
local M = {}
---@param path string
---@return table
local function get_entries(path)
local result = {}
local handle = vim.loop.fs_scandir(path)
if not handle then return result end
while true do
local name, type = vim.loop.fs_scandir_next(handle)
if not name then break end
-- Check if this is a project file
local is_project = false
if type == "file" then
local ext = name:match("%.([^%.]+)$")
if ext == "project" then
is_project = true
type = "project"
end
end
table.insert(result, {
name = name .. (type == "directory" and "/" or ""),
type = type,
full_path = path .. "/" .. name,
is_project = is_project
})
end
table.sort(result, function(a, b)
-- Sort projects first, then directories, then files
if a.is_project ~= b.is_project then
return a.is_project
end
if a.type == "directory" and b.type ~= "directory" then
return true
end
if b.type == "directory" and a.type ~= "directory" then
return false
end
return a.name < b.name
end)
return result
end
---@param list table
---@param query string
---@return table
local function fuzzy_filter(list, query)
local result = {}
query = query:lower()
for _, entry in ipairs(list) do
if entry.name:lower():find(query) then
table.insert(result, entry)
end
end
return result
end
local loaded_languages = {}
---@param lang string
---@param opts? table
---@return boolean
function M.load_language_module(lang, opts)
if loaded_languages[lang] then return true end
local ok, mod = pcall(require, "Polydev.languages")
if not ok or type(mod.languages) ~= "table" then
return false
end
local lang_mod = mod.languages[lang]
if type(lang_mod) ~= "table" or type(lang_mod.setup) ~= "function" then
return false
end
lang_mod:setup(opts and opts[lang] or {})
loaded_languages[lang] = lang_mod
return true
end
---@param project_root string
function M.manager(project_root)
local templates = require("Polydev.templates")
local Popup = require("nui.popup")
local Layout = require("nui.layout")
local event = require("nui.utils.autocmd").event
local cwd = vim.fn.expand(vim.fn.getcwd())
local entries = get_entries(cwd)
local current_view = vim.deepcopy(entries)
-- Create a new custom highlight group with Normal background and NormalFloat foreground
vim.api.nvim_set_hl(0, "CustomFloatText", {
fg = vim.api.nvim_get_hl_by_name("NormalFloat", true).foreground,
bg = vim.api.nvim_get_hl_by_name("Normal", true).background,
})
local popup, search, preview = Popup({
enter = true,
focusable = true,
border = {
style = "rounded", -- "double", "none", "rounded", "shadow", "single" or "solid".
text = { top = " Results ", top_align = "center" },
},
position = "50%",
buf_options = { modifiable = true, readonly = false },
win_options = {
winhighlight = "Normal:CustomFloatText,FloatBorder:Function",
}
}), Popup({
enter = false,
focusable = true,
border = {
style = "rounded", -- "rounded", "single" or "solid".
text = { top = " Find Files ", top_align = "center" },
},
buf_options = { modifiable = true, readonly = false },
win_options = {
winhighlight = "Normal:CustomFloatText,FloatBorder:Function",
}
}), Popup({
enter = false,
focusable = false,
border = {
style = "rounded",
text = { top = " Grep Preview ", top_align = "center" },
},
position = "50%",
buf_options = { modifiable = true, readonly = false },
win_options = {
winhighlight = "Normal:CustomFloatText,FloatBorder:Function",
}
})
local layout = Layout({
position = "55%",
size = { width = "81%", height = "90%" },
},
Layout.Box({
Layout.Box({
Layout.Box(search, { size = "10%" }),
Layout.Box(popup, { size = "93%" }),
}, { dir = "col", size = "48%" }),
Layout.Box(preview, { size = "51.5%" }),
}, { dir = "row" })
)
layout:mount()
local function get_selected_entry()
local row = vim.api.nvim_win_get_cursor(popup.winid)[1] - 1
return current_view[row], row
end
local function update_preview()
if not preview.bufnr then return end
vim.api.nvim_buf_set_lines(preview.bufnr, 0, -1, false, {}) -- Clear
local entry = get_selected_entry()
if not entry then return end
if entry.type == "file" or entry.type == "project" then
-- Preview file contents (first 100 lines)
local lines = {}
local fd = io.open(entry.full_path, "r")
if fd then
for i = 1, 100 do
local line = fd:read("*line")
if not line then break end
table.insert(lines, line)
end
fd:close()
else
table.insert(lines, "[Failed to read file]")
end
vim.api.nvim_buf_set_lines(preview.bufnr, 0, -1, false, lines)
elseif entry.type == "directory" then
-- List contents of directory
local contents = get_entries(entry.full_path)
local lines = {}
for _, item in ipairs(contents) do
table.insert(lines, string.format("- %s", item.name))
end
if #lines == 0 then
table.insert(lines, "[Empty folder]")
end
vim.api.nvim_buf_set_lines(preview.bufnr, 0, -1, false, lines)
end
end
vim.api.nvim_create_autocmd("CursorMoved", {
buffer = popup.bufnr,
callback = function()
vim.schedule(update_preview)
end,
})
local function refresh()
entries = get_entries(cwd)
local root = vim.fn.expand(project_root)
-- If we're not in the Projects folder, redirect to Projects
if not cwd:find(root, 1, true) then
cwd = root
entries = get_entries(cwd)
end
-- Only add ".." if we're inside Projects and not at the root
if cwd ~= root then
table.insert(entries, 1, {
name = "../",
type = "directory",
full_path = vim.fn.fnamemodify(cwd, ":h"),
is_up = true
})
end
current_view = vim.deepcopy(entries)
end
local function render()
local hints = {
"",
"/ → Find a → New Directory % → New File R → Rename",
"x → New Helper File d → New Project D → Delete",
}
if not popup.bufnr then return end
vim.api.nvim_buf_set_lines(popup.bufnr, 0, -1, false, {})
for i, item in ipairs(current_view) do
local line = string.format("%-2d | %-27s | %-6s", i, item.name, item.type)
vim.api.nvim_buf_set_lines(popup.bufnr, -1, -1, false, { line })
end
vim.api.nvim_buf_set_lines(popup.bufnr, -1, -1, false, hints)
update_preview()
end
local function prompt_filter()
vim.api.nvim_buf_set_lines(search.bufnr, 0, -1, false, { "" })
vim.api.nvim_buf_set_option(search.bufnr, "modifiable", true)
if vim.api.nvim_win_is_valid(search.winid) then
vim.api.nvim_set_current_win(search.winid)
end
vim.cmd("startinsert")
vim.keymap.set("i", "<CR>", function()
local input = vim.api.nvim_buf_get_lines(search.bufnr, 0, 1, false)[1]
if input ~= "" then
current_view = fuzzy_filter(entries, input)
render()
end
vim.api.nvim_buf_set_lines(search.bufnr, 0, -1, false, { "" })
vim.api.nvim_set_current_win(popup.winid)
vim.cmd("stopinsert") -- exit insert mode
end, { buffer = search.bufnr, noremap = true })
vim.keymap.set("i", "<Esc>", function()
vim.api.nvim_set_current_win(popup.winid)
vim.cmd("stopinsert") -- ensure we are in normal mode
end, { buffer = search.bufnr, noremap = true })
end
popup:map("n", "/", function() vim.schedule(prompt_filter) end)
-- Mappings
popup:map("n", "<ESC>", function() popup:unmount() end)
-- Creates new file
popup:map("n", "%", function()
vim.ui.input({ prompt = "Enter language for new file: " }, function(lang)
if not lang or lang == "" then return print("File creation canceled") end
if M.load_language_module(lang) and templates.files[lang] and templates.files[lang].run then
popup:unmount()
vim.schedule(function()
vim.ui.input({ prompt = "Enter file name: " }, function(file_name)
if not file_name or file_name == "" then return print("File creation canceled") end
templates.files[lang].run(file_name)
end)
end)
else
print("Error: No File creation method for " .. lang)
end
end)
end)
-- Creates extra file
popup:map("n", "x", function()
vim.ui.input({ prompt = "Enter language for new auxilary file: "}, function(lang)
if not lang or lang == "" then return print("File create canceled") end
if M.load_language_module(lang) and templates.extras.run then
popup:unmount()
vim.schedule(function()
vim.ui.input({ prompt = "Enter file name: "}, function(file_name)
if not file_name or file_name == "" then return print("File creation canceled") end
templates.extras.run(lang, file_name)
end)
end)
else
print("Error: No File creation method for " .. lang)
end
end)
end)
-- Creates a new folder
popup:map("n", "a", function()
vim.ui.input({ prompt = "New folder name:" }, function(input)
if input then
vim.fn.mkdir(cwd .. "/" .. input, "p")
refresh()
render()
end
end)
end)
-- Creates new project
popup:map("n", "d", function()
local opts = {}
vim.ui.input({ prompt = "Enter language for project: " }, function(lang)
if not lang or lang == "" then return print("Project creation canceled") end
opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get(lang), opts or {})
if M.load_language_module(lang) and templates.projects[lang] and templates.projects[lang].run then
-- if templates.projects[lang] and templates.projects[lang].run then
popup:unmount()
vim.schedule(function()
vim.ui.input({ prompt = "Enter project name: " }, function(project_name)
if not project_name or project_name == "" then return print("Project creation canceled") end
templates.projects[lang].run(project_name, opts.project_root)
end)
end)
else
print("Error: No project creation method for " .. lang)
end
end)
end)
-- Deletes Folder and confirms deletion
popup:map("n", "D", function()
local entry = get_selected_entry()
if not entry.is_up then
vim.ui.input({ prompt = "Deletion of " .. entry.name .. ": (y/N) Defaults to N: " }, function(input)
if input == "y" or input == "Y" then
vim.fn.delete(entry.full_path, "rf")
refresh()
render()
end
end)
end
end)
-- Renames Files and Folders
popup:map("n", "R", function()
local entry = get_selected_entry()
if not entry.is_up then
vim.ui.input({ prompt = "Rename:", default = entry.name }, function(input)
if input then
local new_path = cwd .. "/" .. input
vim.fn.rename(entry.full_path, new_path)
refresh()
render()
end
end)
end
end)
-- Changes working directory or edits a file
popup:map("n", "<CR>", function()
local entry = get_selected_entry()
if entry.type == "directory" then
cwd = entry.full_path
vim.cmd("cd " .. cwd)
refresh()
render()
end
if entry.type == "file" then
popup:unmount()
vim.schedule(function()
vim.cmd("edit " .. vim.fn.fnameescape(entry.full_path))
end)
end
end)
popup:map("n", "<BS>", function()
local parent = vim.fn.fnamemodify(cwd, ":h")
if parent ~= cwd then
cwd = parent
refresh()
render()
end
end)
popup:on(event.BufLeave, function()
vim.defer_fn(function()
local function is_valid_win(winid)
return type(winid) == "number" and vim.api.nvim_win_is_valid(winid)
end
if not is_valid_win(popup.winid) and not is_valid_win(search.winid) then
popup:unmount()
end
end, 50)
end)
popup:mount()
refresh()
render()
end
return M
-95
View File
@@ -1,95 +0,0 @@
local M = {}
M.opts = {}
function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("terminal"), opts or {})
end
---@param path string
---@return boolean|nil
function M.is_dir(path)
local stat = vim.loop.fs_stat(path)
return stat and stat.type == "directory"
end
---@return string
function M.get_project_root()
local plugin_dir = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":h:h:h")
local dir = vim.fn.system(plugin_dir .. "/bash_scripts/walkup.sh"):gsub("%s+$", "")
return dir
end
---@return string
function M.get_project_name()
local root = M.get_project_root()
return vim.fn.fnamemodify(root, ":t")
end
---@param path_segments table
---@param content string
function M.write_file(path_segments, content)
local path = table.concat(path_segments, "/")
local file = assert(io.open(path, "w"), "Error creating file: " .. path)
file:write(content)
file:close()
vim.cmd("edit " .. path)
end
---@param path string
---@param gitignore_lines table
function M.init_git(path, gitignore_lines)
vim.fn.mkdir(path, "p")
vim.fn.system({ "git", "-C", path, "init" })
if gitignore_lines and #gitignore_lines > 0 then
local gitignore_path = { path, ".gitignore" }
local contents = table.concat(gitignore_lines, "\n")
M.write_file(gitignore_path, contents)
end
end
---@param cmd table
---@return integer, integer
function M.terminal(cmd)
local opts = require("Polydev.presets").getPresets(M.opts.preset)
local ui = vim.api.nvim_list_uis()[1]
local width
local height
local row
local col
if opts ~= nil then
width = math.max(1, math.floor(ui.width * 0.9) - opts.left_padding - opts.right_padding)
height = math.max(1, math.floor(ui.height * 0.9) - opts.top_padding - opts.bottom_padding)
row = math.floor((ui.height - height) / 2) + opts.top_padding
col = math.floor((ui.width - width) / 2) + opts.left_padding
end
if opts == nil then
width = math.max(1, math.floor(ui.width * 0.9))
height = math.max(1, math.floor(ui.height * 0.9))
row = math.floor((ui.height - height) / 2)
col = math.floor((ui.width - width) / 2)
end
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = M.opts.border.enabled and M.opts.border.type,
})
vim.api.nvim_set_option_value("winblend", vim.o.pumblend, { win = win })
vim.api.nvim_set_option_value("winhighlight", "Normal:Pmenu,FloatBorder:Pmenu", { win = win })
vim.api.nvim_set_option_value("cursorline", true, { win = win })
vim.api.nvim_set_option_value("scrolloff", 5, { win = win })
vim.fn.termopen(table.concat(cmd, "/"))
vim.api.nvim_buf_set_keymap(buf, "n", "<ESC>", "i<C-\\><C-n>:q<CR>", { noremap = true, silent = true })
return buf, win
end
return M
+83
View File
@@ -0,0 +1,83 @@
local M = {}
local utils = require("vern-nvim.utils")
---@param root string
M.create_project = function(root)
local build_cmd = "cd " .. root .. " && cmake -S . -B build && cmake --build build"
local _ = vim.system({ "sh", "-c", build_cmd }):wait()
end
---@param opts VernCConfig
M.create_file = function(opts)
opts = opts or {}
vim.ui.input({ prompt = "Enter type (c/h): " }, function(ft)
ft = ft and vim.trim(ft)
if not ft or ft == "" then
return
end
local mod = {}
if ft == "c" then
mod = opts.c.templates.file.source or {}
end
if ft == "h" then
mod = opts.c.templates.file.header or {}
end
vim.ui.input({ prompt = "Enter file name: " }, function(fname)
fname = fname and vim.trim(fname)
if not fname or fname == "" then
return
end
local raw_path = vim.fs.joinpath(mod.path, mod.name)
local context = {
project_name = utils.proj_name(),
company_name = opts.env.author,
file_name = fname,
}
local path = utils.resolve_path(raw_path, opts.c.dirs or {}, context)
local root = utils.proj_root()
utils.dump(
vim.fs.joinpath(root, path),
require("vern-nvim.templates").fetch(mod.kind_path, mod.kind, context)
)
vim.cmd.edit(vim.fn.expand(path))
vim.notify(fname .. " has been created!", vim.log.levels.INFO, { title = "Vern File" })
end)
end)
end
---@param opts? VernCConfig Takes a table for the runtime
function M.run(opts)
opts = opts or {}
local root = utils.proj_root() or "."
local pname = vim.fs.basename(root)
local build_dir = root .. "/build"
local build_cmd = "cd " .. build_dir .. " && cmake --build ."
vim.system({ "sh", "-c", build_cmd }, { text = true }, function(obj)
if obj.code ~= 0 then
vim.schedule(function()
local error_obj = (obj.stderr ~= "" and obj.stderr) or obj.stdout or ""
local error_lines = vim.list_extend(
{ "Error During compilation" },
vim.split(error_obj, "\n", { trimempty = true })
)
local buf, _ = utils.term({ "echo 'compilation failed'" }, opts.terminal, true)
if buf and vim.api.nvim_buf_is_valid(buf) then
vim.api.nvim_set_option_value("modifiable", true, { buf = buf })
vim.api.nvim_buf_set_lines(buf, 0, -1, false, error_lines)
vim.api.nvim_set_option_value("modifiable", false, { buf = buf })
end
end)
else
vim.schedule(function()
local run_cmd = "cd '" .. build_dir .. "' && ./" .. pname
utils.term({ run_cmd }, opts.terminal, false)
end)
end
end)
end
return M
+83
View File
@@ -0,0 +1,83 @@
local M = {}
local utils = require("vern-nvim.utils")
---@param root string
M.create_project = function(root)
local build_cmd = "cd " .. root .. " && cmake -S . -B build && cmake --build build"
local _ = vim.system({ "sh", "-c", build_cmd }):wait()
end
---@param opts VernCPPConfig
M.create_file = function(opts)
opts = opts or {}
vim.ui.input({ prompt = "Enter type (c/h): " }, function(ft)
ft = ft and vim.trim(ft)
if not ft or ft == "" then
return
end
local mod = {}
if ft == "c" then
mod = opts.cpp.templates.file.source or {}
end
if ft == "h" then
mod = opts.cpp.templates.file.header or {}
end
vim.ui.input({ prompt = "Enter file name: " }, function(fname)
fname = fname and vim.trim(fname)
if not fname or fname == "" then
return
end
local raw_path = vim.fs.joinpath(mod.path, mod.name)
local context = {
project_name = utils.proj_name(),
company_name = opts.env.author,
file_name = fname,
}
local path = utils.resolve_path(raw_path, opts.cpp.dirs or {}, context)
local root = utils.proj_root()
utils.dump(
vim.fs.joinpath(root, path),
require("vern-nvim.templates").fetch(mod.kind_path, mod.kind, context)
)
vim.cmd.edit(vim.fn.expand(path))
vim.notify(fname .. " has been created!", vim.log.levels.INFO, { title = "Vern File" })
end)
end)
end
---@param opts? VernCPPConfig Takes a table for the runtime
function M.run(opts)
opts = opts or {}
local root = utils.proj_root() or "."
local pname = vim.fs.basename(root)
local build_dir = root .. "/build"
local build_cmd = "cd " .. build_dir .. " && cmake --build ."
vim.system({ "sh", "-c", build_cmd }, { text = true }, function(obj)
if obj.code ~= 0 then
vim.schedule(function()
local error_obj = (obj.stderr ~= "" and obj.stderr) or obj.stdout or ""
local error_lines = vim.list_extend(
{ "Error During compilation" },
vim.split(error_obj, "\n", { trimempty = true })
)
local buf, _ = utils.term({ "echo 'compilation failed'" }, opts.terminal, true)
if buf and vim.api.nvim_buf_is_valid(buf) then
vim.api.nvim_set_option_value("modifiable", true, { buf = buf })
vim.api.nvim_buf_set_lines(buf, 0, -1, false, error_lines)
vim.api.nvim_set_option_value("modifiable", false, { buf = buf })
end
end)
else
vim.schedule(function()
local run_cmd = "cd '" .. build_dir .. "' && ./" .. pname
utils.term({ run_cmd }, opts.terminal, false)
end)
end
end)
end
return M
+150
View File
@@ -0,0 +1,150 @@
local M = {}
---TODO
---Split filetype only and just change a filetype variable and vairables both share and then run the duplicate code
local utils = require("vern-nvim.utils")
local templates = require("vern-nvim.templates")
M.create_project = function(opts)
opts = opts or {}
vim.ui.input(
{ prompt = "Project language (e.g. python): ", completion = "filetype" },
function(ft)
ft = ft and vim.trim(ft)
if not ft or vim.trim(ft) == "" then
vim.notify("Unknown Filetype: " .. ft, vim.log.levels.WARN, {
title = "Vern Project",
})
return
end
local ok, actions = pcall(require, "vern-nvim.actions." .. ft)
local configs = require("vern-nvim.configs." .. ft)
local args = vim.tbl_deep_extend("force", {}, configs, opts or {})
vim.ui.input({ prompt = "Enter project name: " }, function(pname)
pname = pname and vim.trim(pname)
if not pname or pname == "" then
return
end
local root =
vim.fs.joinpath(vim.fn.expand(args.workspace_root), args[ft].root, pname)
local ctx = {
project_name = pname,
company_name = args.env.author,
file_name = "",
}
vim.fn.mkdir(root, "p")
for _, dir in pairs(args[ft].dirs) do
local path = vim.fs.normalize(vim.fs.joinpath(root, utils.fmt(dir, ctx)))
vim.fn.mkdir(path, "p")
end
local bin
for tbl_name, tbl in pairs(args[ft].templates.project) do
local raw_path = vim.fs.joinpath(tbl.path, tbl.name)
local path = utils.resolve_path(raw_path, args[ft].dirs, ctx)
if tbl_name == "primary" then
bin = vim.fs.joinpath(root, path)
end
local abs_file_path = vim.fs.normalize(vim.fs.joinpath(root, path))
local abs_dir_path = vim.fs.dirname(abs_file_path)
if abs_dir_path ~= root and not vim.startswith(root, abs_dir_path) then
vim.fn.mkdir(abs_dir_path, "p")
end
utils.dump(abs_file_path, templates.fetch(tbl.kind_path, tbl.kind, ctx))
end
for _, tbl in pairs(args[ft].templates.extras) do
if tbl.enabled then
local raw_path = vim.fs.joinpath(tbl.path, tbl.name)
local path = utils.resolve_path(raw_path, args[ft].dirs, ctx)
local abs_file_path = vim.fs.normalize(vim.fs.joinpath(root, path))
local abs_dir_path = vim.fs.dirname(abs_file_path)
if abs_dir_path ~= root and not vim.startswith(root, abs_dir_path) then
vim.fn.mkdir(abs_dir_path, "p")
end
utils.dump(abs_file_path, templates.fetch(tbl.kind_path, tbl.kind, ctx))
end
end
utils.init_git(root, ft)
utils.init_readme(root)
if ok and actions and type(actions.create_project) == "function" then
actions.create_project(root)
end
vim.cmd.edit(vim.fn.fnameescape(bin))
vim.notify(
"Project: " .. pname .. " has been created!",
vim.log.levels.INFO,
{ title = "Vern Project" }
)
end)
end
)
end
M.create_file = function(opts)
opts = opts or {}
local filetype = vim.bo.filetype
local function continue_filetype(ft)
filetype = ft
local ok, actions = pcall(require, "vern-nvim.actions." .. filetype)
if not ok then
vim.notify("Unknown Filetype: " .. filetype, vim.log.levels.WARN, {
title = "Vern File",
})
return
end
local configs = require("vern-nvim.configs." .. filetype)
local args = vim.tbl_deep_extend("force", {}, configs, opts or {})
vim.ui.input({ prompt = "Enter file name: " }, function(fname)
fname = fname and vim.trim(fname)
if not fname or fname == "" then
return
end
local mod
if ok and actions and type(actions.create_file) == "function" then
mod = actions.create_file(args[filetype])
or args[filetype].templates.file.source
or {}
end
local raw_path = vim.fs.joinpath(mod.path, mod.name)
local context = {
project_name = utils.proj_name(),
company_name = opts.env.author,
file_name = fname,
}
local path = utils.resolve_path(raw_path, args[filetype].dirs or {}, context)
local root = utils.proj_root()
utils.dump(
vim.fs.joinpath(root, path),
templates.fetch(mod.kind_path, mod.kind, context)
)
vim.cmd.edit(vim.fn.fnameescape(path))
vim.notify(fname .. " has been created!", vim.log.levels.INFO, { title = "Vern File" })
end)
end
local ft_ok, ft_config = pcall(require, "vern-nvim.configs." .. filetype)
if not filetype or filetype == "" or not ft_ok or type(ft_config) ~= "table" then
vim.ui.input({
prompt = "File language (e.g. python): ",
completion = "filetype",
}, function(ft)
ft = ft and vim.trim(ft)
if not ft or vim.trim(ft) == "" then
return
end
continue_filetype(ft)
end)
else
continue_filetype(filetype)
end
end
return M
+58
View File
@@ -0,0 +1,58 @@
local M = {}
local utils = require("vern-nvim.utils")
M.create_project = function() end
M.create_file = function() end
---@param opts VernJavaConfig Takes a table for the runtime
function M.run(opts)
opts = opts or {}
local root = utils.proj_root() or "."
local context = {
project_name = utils.proj_name(),
company_name = opts.env.author,
file_name = "",
}
local src_root =
vim.fs.joinpath(root, utils.resolve_path(opts.java.dirs.src, opts.java.dirs, context))
local build_dir = root .. "/bin"
local build_cmd = string.format(
"javac -d %s -sourcepath %s $(find %s -name '*java')",
build_dir,
src_root,
src_root
)
vim.system({ "sh", "-c", build_cmd }, { text = true }, function(obj)
if obj.code ~= 0 then
vim.schedule(function()
local error_obj = (obj.stderr ~= "" and obj.stderr) or obj.stdout or ""
local error_lines = vim.list_extend(
{ "Error During compilation" },
vim.split(error_obj, "\n", { trimempty = true })
)
local buf, _ = utils.term({ "echo 'compilation failed'" }, opts.terminal, true)
if buf and vim.api.nvim_buf_is_valid(buf) then
vim.api.nvim_set_option_value("modifiable", true, { buf = buf })
vim.api.nvim_buf_set_lines(buf, 0, -1, false, error_lines)
vim.api.nvim_set_option_value("modifiable", false, { buf = buf })
end
end)
else
vim.schedule(function()
local run_cmd = string.format(
"java -cp %s com.%s.%s.Main",
build_dir,
context.company_name,
context.project_name
)
utils.term({ run_cmd }, opts.terminal, false)
end)
end
end)
end
return M
+21
View File
@@ -0,0 +1,21 @@
local M = {}
local utils = require("vern-nvim.utils")
M.create_project = function() end
M.create_file = function() end
---@param opts VernCPPConfig Takes a table for the runtime
function M.run(opts)
opts = opts or {}
local root = utils.proj_root() or "."
local pname = vim.fs.basename(root)
local full_path = vim.fs.joinpath(root, "lua", pname)
print(full_path .. "/init.lua")
utils.term({ "lua " .. full_path .. "/init.lua" }, opts.terminal or {}, false)
end
return M
+49
View File
@@ -0,0 +1,49 @@
local M = {}
local utils = require("vern-nvim.utils")
---@param root string
M.create_project = function(root)
vim.fn.system("python3 -m venv " .. root .. "/venv")
end
M.create_file = function() end
---@param opts VernPythonConfig Takes a table for the runtime
function M.run(opts)
opts = opts or {}
local root = utils.proj_root() or "."
local context = {
project_name = utils.proj_name(),
company_name = opts.env.author,
file_name = "",
}
local bin = opts.python.templates.project.primary
local exe = vim.fs.joinpath(bin.path, bin.name) or "src/{project_name}/main.py"
local exe_path = utils.resolve_path(exe, opts.python.dirs, context)
local full_path = vim.fs.joinpath(vim.fn.expand(root), exe_path)
utils.term({ "python3 " .. full_path }, opts.terminal or {}, false)
end
function M.pip_install()
vim.ui.input({ prompt = "Enter pip module: " }, function(mod)
mod = mod and vim.trim(mod)
if not mod or mod == "" then
vim.notify("Pip Cancelled", vim.log.levels.WARN)
return
end
vim.notify("Installing " .. mod, vim.log.levels.INFO)
vim.system({ "pip", "install", mod }, { text = true }, function(obj)
vim.schedule(function()
if obj.code ~= 0 then
vim.notify("Pip failed: " .. obj.stderr, vim.log.levels.WARN)
else
vim.notify("Pip installed " .. mod, vim.log.levels.INFO)
end
end)
end)
end)
end
return M
+71
View File
@@ -0,0 +1,71 @@
local M = {}
M.attach = function() end
---@type VernLanguageConfig
M.c = {
root = "C",
dirs = {
src = "src",
include = "include/{project_name}",
},
keybinds = {
["<leader>pr"] = {
user_command = "CRun",
desc = "Executes c code",
action = require("vern-nvim.actions.c").run,
},
["<leader>pf"] = {
user_command = "CCreateFile",
desc = "Creates source/header files",
action = require("vern-nvim.actions.c").create_file,
},
},
templates = {
project = {
primary = {
path = "{dirs.src}",
name = "main.c",
kind = "main",
kind_path = "vern-nvim.templates.c",
},
manifest = {
path = ".",
name = "CMakeLists.txt",
kind = "CmakeLists",
kind_path = "vern-nvim.templates.c",
},
style = {
path = ".",
name = ".clang-format",
kind = "format",
kind_path = "vern-nvim.templates.c",
},
},
file = {
header = {
path = "{dirs.include}",
name = "{file_name}.h",
kind = "header",
kind_path = "vern-nvim.templates.c",
},
source = {
path = "{dirs.src}",
name = "{file_name}.c",
kind = "source",
kind_path = "vern-nvim.templates.c",
},
},
extras = {
linter = {
path = ".",
name = ".clang-tidy",
kind = "linter",
kind_path = "vern-nvim.templates.c",
enabled = false,
},
},
},
}
return M
+71
View File
@@ -0,0 +1,71 @@
local M = {}
M.attach = function() end
---@type VernLanguageConfig
M.cpp = {
root = "CPP",
dirs = {
src = "src",
include = "include/{project_name}",
},
keybinds = {
["<leader>pr"] = {
user_command = "CPPRun",
desc = "Executes cpp code",
action = require("vern-nvim.actions.cpp").run,
},
["<leader>pf"] = {
user_command = "CPPCreateFile",
desc = "Creates source/header files",
action = require("vern-nvim.actions.cpp").create_file,
},
},
templates = {
project = {
primary = {
path = "{dirs.src}",
name = "main.cpp",
kind = "main",
kind_path = "vern-nvim.templates.cpp",
},
manifest = {
path = ".",
name = "CMakeLists.txt",
kind = "CmakeLists",
kind_path = "vern-nvim.templates.cpp",
},
style = {
path = ".",
name = ".clang-format",
kind = "format",
kind_path = "vern-nvim.templates.cpp",
},
},
file = {
header = {
path = "{dirs.include}",
name = "{file_name}.hpp",
kind = "header",
kind_path = "vern-nvim.templates.cpp",
},
source = {
path = "{dirs.src}",
name = "{file_name}.cpp",
kind = "source",
kind_path = "vern-nvim.templates.cpp",
},
},
extras = {
linter = {
path = ".",
name = ".clang-tidy",
kind = "linter",
kind_path = "vern-nvim.templates.cpp",
enabled = false,
},
},
},
}
return M
+46
View File
@@ -0,0 +1,46 @@
local actions = require("vern-nvim.actions")
---@type VernCoreConfig
return {
workspace_root = "~/personal/Projects",
env = {
--- In documentation, make recommendation to change to username or name instead of company
author = "company",
},
keybinds = {
["<leader>pc"] = {
user_command = "VernCreateProject",
desc = "Creates a new project",
action = actions.create_project,
},
["<leader>pf"] = {
user_command = "VernCreateFile",
desc = "Creates a new project file",
action = actions.create_file,
},
},
terminal = {
mode = {
type = "split",
win = {
float = {
padding = {
left = 0,
right = 0,
top = 0,
bottom = 0,
},
border = {
enabled = true,
type = vim.o.winborder, -- defaults to neovim winborder
},
},
split = {
direction = "horizontal",
anchor = "bottom",
size = "20",
},
},
},
},
}
+45
View File
@@ -0,0 +1,45 @@
local M = {}
M.attach = function() end
---@type VernLanguageConfig
M.java = {
root = "Java",
dirs = {
src = "src/com/{company_name}/{project_name}",
bin = "bin",
},
keybinds = {
["<leader>pr"] = {
user_command = "JavaRun",
desc = "Executes java code",
action = require("vern-nvim.actions.java").run,
},
},
templates = {
project = {
primary = {
path = "{dirs.src}",
name = "Main.java",
kind = "main",
kind_path = "vern-nvim.templates.java",
},
style = {
path = ".",
name = ".clang-format",
kind = "format",
kind_path = "vern-nvim.templates.java",
},
},
file = {
source = {
path = "{dirs.src}",
name = "{file_name}.java",
kind = "source",
kind_path = "vern-nvim.templates.java",
},
},
extras = {},
},
}
return M
+45
View File
@@ -0,0 +1,45 @@
local M = {}
M.attach = function() end
---@type VernLanguageConfig
M.lua = {
root = "Lua",
dirs = {
src = "lua/{project_name}",
},
keybinds = {
["<leader>pr"] = {
user_command = "LuaRun",
desc = "Executes lua code",
action = require("vern-nvim.actions.lua").run,
},
},
templates = {
project = {
primary = {
path = "{dirs.src}",
name = "init.lua",
kind = "init",
kind_path = "vern-nvim.templates.lua",
},
style = {
path = ".",
name = "stylua.toml",
kind = "format",
kind_path = "vern-nvim.templates.lua",
},
},
file = {
source = {
path = "{dirs.src}",
name = "{file_name}.lua",
kind = "source",
kind_path = "vern-nvim.templates.lua",
},
},
extras = {},
},
}
return M
+70
View File
@@ -0,0 +1,70 @@
local M = {}
M.attach = function()
local root = require("vern-nvim.utils").proj_root()
if not root then
return
end
local venv_dir = nil
if vim.uv.fs_stat(root .. "/venv/bin/python") then
venv_dir = root .. "/venv"
elseif vim.uv.fs_stat(root .. "/.venv/bin/python") then
venv_dir = root .. "/.venv"
end
if venv_dir then
vim.env.VIRTUAL_ENV = venv_dir
vim.env.PATH = venv_dir .. "/bin:" .. vim.env.PATH
end
end
---@type VernLanguageConfig
M.python = {
root = "Python",
dirs = {
src = "src/{project_name}",
},
keybinds = {
["<leader>pr"] = {
user_command = "Pythonrun",
desc = "Executes python code",
action = require("vern-nvim.actions.python").run,
},
["<leader>pi"] = {
user_command = "Pythonpip",
desc = "Install python packages for environment",
action = require("vern-nvim.actions.python").pip_install,
},
},
templates = {
project = {
primary = {
path = "{dirs.src}",
name = "main.py",
kind = "main",
kind_path = "vern-nvim.templates.python",
},
manifest = {
path = ".",
name = "pyproject.toml",
kind = "pyproject",
kind_path = "vern-nvim.templates.python",
},
pkg_init = {
path = "{dirs.src}",
name = "__init__.py",
kind = "__init__",
kind_path = "vern-nvim.templates.python",
},
},
file = {
source = {
path = "{dirs.src}",
name = "{file_name}.py",
kind = "module",
kind_path = "vern-nvim.templates.python",
},
},
extras = {},
},
}
return M
+157
View File
@@ -0,0 +1,157 @@
local ok, health = pcall(require, "vim.health")
if not ok then
health = nil
end
local new_api = health ~= nil and type(health.start) == "function"
local function report_start(name)
if new_api then health.start(name) else vim.health.report_start(name) end
end
local function report_ok(msg)
if new_api then health.ok(msg) else vim.health.report_ok(msg) end
end
local function report_info(msg)
if new_api then health.info(msg) else vim.health.report_info(msg) end
end
local function report_warn(msg, advice)
if new_api then
health.warn(msg, advice)
else
vim.health.report_warn(msg, advice)
end
end
local function report_error(msg, advice)
if new_api then
health.error(msg, advice)
else
vim.health.report_error(msg, advice)
end
end
local M = {}
local function fmt_langs(langs)
if type(langs) == "table" then
return "[" .. table.concat(langs, ", ") .. "]"
end
return "[" .. tostring(langs) .. "]"
end
local function check_nvim_version()
if vim.fn.has("nvim-0.10") == 1 then
report_ok(string.format("Neovim %s detected.", tostring(vim.version())))
else
report_error("Polydev requires Neovim 0.10 or newer.", "You are running " .. tostring(vim.version()))
end
end
local function check_setup()
local ok_configs, configs = pcall(require, "Polydev.configs")
if not ok_configs then
report_error("Could not load Polydev.configs", tostring(configs))
return nil
end
if next(configs.user_config or {}) == nil then
report_warn("Polydev.setup() has not run.",
"Add require('Polydev').setup() to your Neovim config, or make sure plugin/Polydev.lua is sourced by your plugin manager.")
return nil
end
report_ok("Polydev.setup() ran and the config is loaded.")
return configs
end
local function check_project_root(configs)
if not configs then return end
local root = configs.get("globals").project_root
local expanded = vim.fn.expand(root)
if vim.fn.isdirectory(expanded) == 1 then
if vim.fn.filewritable(expanded) == 2 then
report_ok(string.format("project_root exists and is writable: %s", expanded))
else
report_warn(string.format("project_root exists but is not writable: %s", expanded))
end
else
report_warn(string.format("project_root does not exist yet: %s", expanded),
"It is created automatically the first time the manager is opened.")
end
end
local function check_ui_input()
local ok_default, default = pcall(require, "vim.ui")
if ok_default and default.input and vim.ui.input ~= default.input then
report_warn("vim.ui.input has been overridden, likely by a UI plugin such as dressing.nvim or nui.nvim.",
"An asynchronous override can break project/file creation from the manager. Polydev now uses callbacks, but report here if it still misbehaves.")
else
report_ok("vim.ui.input is Neovim's default (synchronous) implementation.")
end
end
local function check_tools()
local tools = {
{ name = "git", langs = "all" },
{ name = "node", langs = "javascript" },
{ name = "python3", langs = "python" },
{ name = "pip3", langs = "python" },
{ name = "javac", langs = "java" },
{ name = "java", langs = "java" },
{ name = "cmake", langs = { "c", "cpp" } },
{ name = "cc", langs = { "c", "cpp" } },
{ name = "clang", langs = { "c", "cpp" } },
{ name = "clang-format", langs = { "c", "cpp" } },
{ name = "clang-tidy", langs = { "c", "cpp" } },
{ name = "cargo", langs = "rust" },
{ name = "lua", langs = "lua" },
{ name = "luajit", langs = "lua" },
}
for _, t in ipairs(tools) do
if vim.fn.executable(t.name) == 1 then
report_ok(string.format("%s is available for %s.", t.name, fmt_langs(t.langs)))
else
report_warn(string.format("%s was not found.", t.name),
"Project templates for " .. fmt_langs(t.langs) .. " may fail without it.")
end
end
if vim.fn.executable("python3") == 1 then
vim.fn.system("python3 -c 'import venv' 2>/dev/null")
if vim.v.shell_error == 0 then
report_ok("python3 venv module is available.")
else
report_warn("python3 venv module is missing.",
"Python project creation sets up a virtualenv and needs python3 -m venv.")
end
end
end
local function check_walkup()
local scripts = vim.api.nvim_get_runtime_file("bash_scripts/walkup.sh", false)
if #scripts == 0 then
report_error("bash_scripts/walkup.sh was not found on the runtimepath.",
"Reinstall the plugin so bash_scripts/ sits next to lua/ and plugin/.")
return
end
local script = scripts[1]
if vim.fn.executable(script) == 1 then
report_ok(string.format("bash_scripts/walkup.sh found and executable: %s", script))
else
report_warn(string.format("bash_scripts/walkup.sh is not executable: %s", script),
"Run: chmod +x " .. script)
end
end
function M.check()
report_start("Polydev")
check_nvim_version()
local configs = check_setup()
check_project_root(configs)
check_ui_input()
check_tools()
check_walkup()
end
return M
+72
View File
@@ -0,0 +1,72 @@
local M = {}
local configs = require("vern-nvim.configs")
---@type VernCoreConfig
M.opts = vim.deepcopy(configs)
---@class VernUserConfig
---@field workspace_root? string
---@field keybinds? table<string, VernKeybindItem>
---@field terminal? VernTerminalConfig | table
---@param user_opts? VernUserConfig
function M.setup(user_opts)
---@type VernCoreConfig
M.opts = vim.tbl_deep_extend("force", {}, configs, user_opts or {})
for key, def in pairs(M.opts.keybinds or {}) do
if type(def.action) == "function" then
vim.api.nvim_create_user_command(def.user_command, function()
def.action(M.opts)
end, { nargs = "*", desc = def.desc })
vim.keymap.set("n", key, function()
def.action(M.opts)
end, {
silent = true,
desc = def.desc,
})
end
end
local group = vim.api.nvim_create_augroup("VernAutocommands", { clear = true })
vim.api.nvim_create_autocmd("FileType", {
group = group,
pattern = "*",
callback = function(args)
local ft = vim.bo[args.buf].filetype
if not ft or ft == "" then
return
end
local has_config, mod = pcall(require, "vern-nvim.configs." .. ft)
if not has_config then
return
end
local opts = vim.tbl_deep_extend("force", {}, mod, M.opts or {})
if opts[ft] and opts[ft].keybinds then
for key, def in pairs(opts[ft].keybinds or {}) do
if type(def.action) == "function" then
vim.api.nvim_buf_create_user_command(args.buf, def.user_command, function()
def.action(opts)
end, { nargs = "*", desc = def.desc })
vim.keymap.set("n", key, function()
def.action(opts)
end, {
buffer = args.buf,
silent = true,
desc = def.desc,
})
end
end
end
local ok, attach_mod = pcall(require, "vern-nvim.configs." .. ft)
if ok and type(attach_mod.attach) == "function" then
attach_mod.attach(args.buf, opts)
end
end,
desc = "Attach languages to buffer",
})
end
return M
+87
View File
@@ -0,0 +1,87 @@
local utils = require("Polydev.utils")
local configs = require("Polydev.configs")
local M = {}
M.languages = {
javascript = {
setup = function(self, user_opts)
local opts =
vim.tbl_deep_extend("force", {}, configs.get("javascript"), user_opts or {})
vim.api.nvim_create_user_command("JavascriptRun", function()
self:run()
end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":JavascriptRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
local cmd = string.format("node " .. root .. "/main.js")
local output = vim.fn.system(cmd)
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(
term_buf,
0,
-1,
false,
vim.list_extend(
{ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true })
)
)
vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
else
utils.terminal({ "node " .. root .. "/main.js" })
end
end,
},
html = {
setup = function(user_opts)
vim.tbl_deep_extend("force", {}, configs.get("html"), user_opts or {})
end,
},
rust = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("rust"), user_opts or {})
vim.api.nvim_create_user_command("RustRun", function()
self:run()
end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":RustRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
if not root then
return print("Error: Project root not found.")
end
local cmd = { "cargo build" }
local output = vim.fn.system(table.concat(cmd))
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal(cmd)
vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(
term_buf,
0,
-1,
false,
vim.list_extend(
{ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true })
)
)
vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
else
utils.terminal({ "cargo run" })
end
end,
},
}
return M
+3
View File
@@ -0,0 +1,3 @@
local M = {}
return M
+82
View File
@@ -0,0 +1,82 @@
local utils = require("Polydev.utils")
local M = {}
M.projects = {
javascript = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.mkdir(full_project_root, "p")
utils.write_file(
{ full_project_root, "main.js" },
[[
console.log("Hello World!");
]]
)
local gitignore = { "" }
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/main.js")
end,
},
rust = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.system("cargo new " .. full_project_root)
vim.cmd("edit " .. full_project_root .. "/src/main.rs")
end,
},
html = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
if vim.fn.isdirectory(full_project_root) == 0 then
vim.fn.mkdir(full_project_root, "p") -- Create directory with parent directories
end
local main_html_content = [[
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>
]]
utils.write_file({ full_project_root, "index.html" }, main_html_content)
end,
},
}
M.files = {
rust = {
run = function(file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".rs" }, "")
end,
},
html = {
run = function(file_name)
utils.write_file(
{ ".", file_name .. ".html" },
string.format([[
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>
]])
)
end,
},
}
return M
+137
View File
@@ -0,0 +1,137 @@
return {
--[[ =====================================================================
TEMPLATE: MAIN (Entrypoint)
File: main.c
Target: src/main.c
===================================================================== --]]
main = vim.trim([=[
#include <stdio.h>
int
main()
{
char* str = "Hello World";
printf("%s\n", str);
return 0;
}
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: CLANG-FORMAT (Code formatter)
File: .clang-format
Target: .clang-format
===================================================================== --]]
format = vim.trim([=[
---
BasedOnStyle: Google
Standard: Latest
UseTab: Always
TabWidth: 8
IndentWidth: 8
BreakBeforeBraces: Allman
SpaceBeforeCpp11BracedList: true
SeparateDefinitionBlocks: Always
Cpp11BracedListStyle: false
BreakAfterReturnType: TopLevel
ReflowComments: Always
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
IndentAccessModifiers: false # Indent access specifiers by one level
AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level
IndentGotoLabels: InnerIndent
DerivePointerAlignment: false
PointerAlignment: Left
IndentPPDirectives: AfterHash
SortIncludes: CaseSensitive
IncludeBlocks: Preserve
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: CMAKELISTS (Spec / Build Manifest)
File: CMakeLists.txt
Target: CMakeLists.txt
===================================================================== --]]
CmakeLists = vim.trim([=[
cmake_minimum_required(VERSION 3.16)
project(__PROJECT_NAME__ LANGUAGES C)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(LIB_SOURCES
# Add your other types here as you implement them:
# src/example1.c
# src/example2.c
)
if(LIB_SOURCES)
add_library(__PROJECT_NAME__ STATIC ${LIB_SOURCES})
target_include_directories(__PROJECT_NAME__
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
endif()
add_executable(__PROJECT_NAME___bin src/main.c)
set_target_properties(__PROJECT_NAME___bin PROPERTIES OUTPUT_NAME "__PROJECT_NAME__")
if(TARGET __PROJECT_NAME__)
target_link_libraries(__PROJECT_NAME___bin PRIVATE __PROJECT_NAME__)
endif()
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: HEADER (Standalone File)
File: {name}.h
Target: include/{project_name}/{name}.h
===================================================================== --]]
header = vim.trim([=[
#ifndef __FILE_NAME___H
#define __FILE_NAME___H
// Code
#endif /* __FILE_NAME___H */
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: SOURCE (Standalone File)
File: {name}.c
Target: src/{name}.c
===================================================================== --]]
source = vim.trim([=[
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: CLANG_TIDY (LINTER)
File: .clang-tidy
Target: .clang-tidy
===================================================================== --]]
linter = vim.trim([=[
Checks: >
-*,
clang-analyzer-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
-bugprone-reserved-identifier,
performance-*,
security-*
readability-redundant-declaration
readability-misleading-indentation
readability-implicit-bool-conversion
misc-misplaced-const,
misc-include-cleaner
-bugprone-narrowing-conversions,
-readability-identifier-length
CheckOptions:
readability-identifier-naming.VariableCase: lower_case
readability-identifier-naming.FunctionCase: lower_case
readability-identifier-naming.StructCase: lower_case
readability-identifier-naming.EnumCase: CamelCase
readability-identifier-naming.EnumConstantCase: UPPER_CASE
readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
]=]) .. "\n",
}
+137
View File
@@ -0,0 +1,137 @@
return {
--[[ =====================================================================
TEMPLATE: MAIN (Entrypoint)
File: main.cpp
Target: src/main.cpp
===================================================================== --]]
main = vim.trim([=[
#include <iostream>
int
main()
{
std::string str = "Hello World";
std::cout << str << "\n";
return 0;
}
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: CLANG-FORMAT (Code formatter)
File: .clang-format
Target: .clang-format
===================================================================== --]]
format = vim.trim([=[
---
BasedOnStyle: Google
Standard: Latest
UseTab: Always
TabWidth: 8
IndentWidth: 8
BreakBeforeBraces: Allman
SpaceBeforeCpp11BracedList: true
SeparateDefinitionBlocks: Always
Cpp11BracedListStyle: false
BreakAfterReturnType: TopLevel
ReflowComments: Always
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
IndentAccessModifiers: false # Indent access specifiers by one level
AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level
IndentGotoLabels: InnerIndent
DerivePointerAlignment: false
PointerAlignment: Left
IndentPPDirectives: AfterHash
SortIncludes: CaseSensitive
IncludeBlocks: Preserve
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: CMAKELISTS (Spec / Build Manifest)
File: CMakeLists.txt
Target: CMakeLists.txt
===================================================================== --]]
CmakeLists = vim.trim([=[
cmake_minimum_required(VERSION 3.16)
project(__PROJECT_NAME__ LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(LIB_SOURCES
# Add your other types here as you implement them:
# src/example1.cpp
# src/example2.cpp
)
if(LIB_SOURCES)
add_library(__PROJECT_NAME__ STATIC ${LIB_SOURCES})
target_include_directories(__PROJECT_NAME__
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
endif()
add_executable(__PROJECT_NAME___bin src/main.cpp)
set_target_properties(__PROJECT_NAME___bin PROPERTIES OUTPUT_NAME "__PROJECT_NAME__")
if(TARGET __PROJECT_NAME__)
target_link_libraries(__PROJECT_NAME___bin PRIVATE __PROJECT_NAME__)
endif()
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: HEADER (Standalone File)
File: {name}.hpp
Target: include/{project_name}/{name}.hpp
===================================================================== --]]
header = vim.trim([=[
#ifndef __FILE_NAME___HPP
#define __FILE_NAME___HPP
// Code
#endif /* __FILE_NAME___HPP */
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: SOURCE (Standalone File)
File: {name}.cpp
Target: src/{name}.cpp
===================================================================== --]]
source = vim.trim([=[
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: CLANG_TIDY (LINTER)
File: .clang-tidy
Target: .clang-tidy
===================================================================== --]]
linter = vim.trim([=[
Checks: >
-*,
clang-analyzer-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
-bugprone-reserved-identifier,
performance-*,
security-*
readability-redundant-declaration
readability-misleading-indentation
readability-implicit-bool-conversion
misc-misplaced-const,
misc-include-cleaner
-bugprone-narrowing-conversions,
-readability-identifier-length
CheckOptions:
readability-identifier-naming.VariableCase: lower_case
readability-identifier-naming.FunctionCase: lower_case
readability-identifier-naming.StructCase: lower_case
readability-identifier-naming.EnumCase: CamelCase
readability-identifier-naming.EnumConstantCase: UPPER_CASE
readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
]=]) .. "\n",
}
@@ -0,0 +1,51 @@
local M = {}
---@param lang string
M.template = function(lang)
local base = [=[
.DS_Store
.vscode/
.idea/
.env
.env.*
]=]
local lang_block = {
python = vim.trim([=[
__pycache__/
build/
dist/
.venv/
env/
venv/
.pytest_cache/
]=]),
c = vim.trim([=[
build/
.cache/
]=]),
cpp = vim.trim([=[
build/
.cache/
]=]),
lua = vim.trim([=[
luac.out
]=]),
java = vim.trim([=[
bin/
*.class
*.jar
]=]),
}
local extra = (lang and lang_block[lang]) or ""
return base .. extra
end
return M
@@ -0,0 +1 @@
return "# Hello from your fellow README.md"
+37
View File
@@ -0,0 +1,37 @@
local M = {}
local registers = {
project_name = "__PROJECT_NAME__",
company_name = "__COMPANY_NAME__",
file_name = "__FILE_NAME__",
}
---@param kind_path string Filetype of template
---@param kind string Template in language table
---@param context table<string, string> A string to replace temp values in template
---@return string Content Formatted string
function M.fetch(kind_path, kind, context)
kind, context = kind or "", context or {}
if not kind or kind == "" then
return ""
end
local ok, mod = pcall(require, kind_path)
if not ok or type(mod) ~= "table" or not mod[kind] then
return ""
end
local template = mod[kind] or ""
context = context or {}
if ok and type(mod) == "table" then
for key, placeholder in pairs(registers) do
local value = context[key]
if value then
template = string.gsub(template, placeholder, value)
end
end
end
return template
end
return M
+65
View File
@@ -0,0 +1,65 @@
return {
--[[ =====================================================================
TEMPLATE: MAIN (Entrypoint)
File: Main.java
Target: src/com/company/app/Main.java
===================================================================== --]]
main = vim.trim([=[
package com.__COMPANY_NAME__.__PROJECT_NAME__;
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: CLANG-FORMAT (Code formatter)
File: .clang-format
Target: .clang-format
===================================================================== --]]
format = vim.trim([=[
---
Language: Java
BasedOnStyle: Google
Standard: Latest
UseTab: Always
TabWidth: 8
IndentWidth: 8
BreakBeforeBraces: Allman
SeparateDefinitionBlocks: Always
BreakAfterReturnType: TopLevel
ReflowComments: Always
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
SortIncludes: CaseSensitive
IncludeBlocks: Preserve
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: SOURCE (Standalone File)
File: {name}.java
Target: src/com/company/app/{name}.java
===================================================================== --]]
source = vim.trim([=[
package com.__COMPANY_NAME__.__PROJECT_NAME__;
public class __FILE_NAME__ {
// Fields / Attributes
private String data;
// Constructor
public __FILE_NAME__() {
}
// Methods
public void doSomething() {
}
}
]=]) .. "\n",
}
View File
+59
View File
@@ -0,0 +1,59 @@
return {
--[[ =====================================================================
TEMPLATE: MAIN (Entrypoint)
File: main.py
Target: src/{project_name}/main.py
===================================================================== --]]
main = vim.trim([=[
def main() -> None:
print("Hello from __PROJECT_NAME__!")
if __name__ == "__main__":
main()
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: INIT (Package Anchor)
File: __init__.py
Target: src/{project_name}/__init__.py
===================================================================== --]]
__init__ = vim.trim([=[
# __PROJECT_NAME__ init
__all__: list[str] = []
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: PYPROJECT (Spec / Build Manifest)
File: pyproject.toml
Target: pyproject.toml
===================================================================== --]]
pyproject = vim.trim([=[
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "__PROJECT_NAME__"
version = "0.1.0"
description = "Project __PROJECT_NAME__"
readme = "README.md"
requires-python = ">=3.10"
dependencies = []
[project.scripts]
__PROJECT_NAME__ = "__PROJECT_NAME__.main:main"
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: MODULE (Standalone File)
File: {name}.py
Target: src/{project_name}/{name}.py
===================================================================== --]]
module = vim.trim([=[
"""
Module: __FILE_NAME__
"""
]=]) .. "\n",
}
+72
View File
@@ -0,0 +1,72 @@
---@alias TerminalModeType "split" | "float"
---@alias SplitDirection "vertical" | "horizontal"
---@alias SplitAnchorType "right" | "bottom"
---@class VernKeybindItem
---@field user_command string
---@field desc string
---@field action function
---@class VernFloatWindowConfig
---@field padding { left: integer, right: integer, top: integer, bottom: integer }
---@field border { enabled: boolean, type: string }
---@class VernSplitWindowConfig
---@field direction SplitDirection
---@field anchor SplitAnchorType
---@field size string
---@class VernWindowConfig
---@field float VernFloatWindowConfig
---@field split VernSplitWindowConfig
---@class VernModeConfig
---@field type TerminalModeType
---@field win VernWindowConfig
---@class VernTerminalConfig
---@field mode VernModeConfig
---@class VernEnvItem
---@field author string
---@class VernCoreConfig
---@field workspace_root string
---@field env VernEnvItem
---@field keybinds table<string, VernKeybindItem>
---@field terminal VernTerminalConfig
---@class VernFileLayout
---@field path string
---@field name string
---@field kind string
---@field kind_path string
---@class VernExtrasLayout : VernFileLayout
---@field enabled boolean
---@class VernLanguageTemplates
---@field project table<string, VernFileLayout>
---@field file table<string, VernFileLayout>
---@field extras table<string, VernExtrasLayout>
---@class VernLanguageConfig
---@field root string
---@field dirs table<string, string>
---@field keybinds table<string, VernKeybindItem>
---@field templates VernLanguageTemplates
---@class VernPythonConfig : VernCoreConfig
---@field python? VernLanguageConfig
---@class VernCConfig : VernCoreConfig
---@field c? VernLanguageConfig
---@class VernCPPConfig : VernCoreConfig
---@field cpp? VernLanguageConfig
---@class VernLuaConfig : VernCoreConfig
---@field lua? VernLanguageConfig
---
---@class VernJavaConfig : VernCoreConfig
---@field java? VernLanguageConfig
+154
View File
@@ -0,0 +1,154 @@
local M = {}
---@param path string
---@param content string
function M.dump(path, content)
local file = assert(io.open(path, "w"), "Error creating file: " .. path)
file:write(content)
file:close()
end
---@param str string String to replace
---@param ctx table<string, string> Replacment characters
---@return string
function M.fmt(str, ctx)
return (str:gsub("{([^}]+)}", ctx))
end
---@param bufnr? integer Default is 0 (current buffer)
function M.proj_root(bufnr)
bufnr = bufnr or 0
local root_markers = {
".git",
"pyproject.toml",
"setup.py",
"Makefile",
"CMakeLists",
"Cargo.toml",
}
return vim.fs.root(bufnr, root_markers) or vim.uv.cwd()
end
---@param raw_path string Combination of tbl.path and tbl.name to override
---@param dir_tbl table<string, string> Strings to replace raw directories in {dirs.<>} with
---@param ctx table<string, string> Strings to replace raw names like {project_name} with
---@return string path Fully replaced path
function M.resolve_path(raw_path, dir_tbl, ctx)
--- Replace the {dirs.<key>}
raw_path = raw_path:gsub("{dirs%.([%w_]+)}", function(dir_key)
return dir_tbl and dir_tbl[dir_key] or dir_key
end)
--- Replace the {<key>}
local path = raw_path:gsub("{([%w_]+)}", function(key)
return ctx and ctx[key] or ("{" .. key .. "}")
end)
return path
end
---@return string
function M.proj_name()
return vim.fn.fnamemodify(M.proj_root(), ":t")
end
---@param path string
---@param ft string
function M.init_git(path, ft)
ft = ft and vim.trim(ft)
if not ft or ft == "" then
return
end
local gitignore = require("vern-nvim.templates.extras.gitignore").template(ft)
vim.fn.system({ "git", "-C", path, "init" })
M.dump(vim.fs.joinpath(path, ".gitignore"), gitignore)
end
---@param path string
function M.init_readme(path)
local readme = require("vern-nvim.templates.extras.readme")
M.dump(vim.fs.joinpath(path, "README.md"), readme)
end
---@param cmd table
---@param opts VernTerminalConfig
---@param scratch boolean
---@return integer, integer?
function M.term(cmd, opts, scratch)
opts = opts or {}
local buf, win
if opts.mode.type == "float" then
local ui = vim.api.nvim_list_uis()[1]
local dim = {
width = math.max(
1,
math.floor(ui.width * 0.9)
- opts.mode.win.float.padding.left
- opts.mode.win.float.padding.right
),
height = math.max(
1,
math.floor(ui.height * 0.9)
- opts.mode.win.float.padding.top
- opts.mode.win.float.padding.bottom
),
}
local pos = {
row = math.floor(
(ui.height - (vim.o.laststatus == 3 and 1 or 0) - vim.o.cmdheight - dim.height) / 2
),
col = math.floor((ui.width - dim.width) / 2),
}
buf = vim.api.nvim_create_buf(false, true)
win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = dim.width,
height = dim.height,
row = pos.row,
col = pos.col,
style = "minimal",
border = opts.mode.win.float.border.enabled and opts.mode.win.float.border.type or nil,
})
if scratch then
return buf, win
end
end
if opts.mode.type == "split" then
if opts.mode.win.split.direction == "vertical" then
if opts.mode.win.split.anchor == "right" then
vim.cmd("set splitright")
end
vim.cmd(opts.mode.win.split.size .. " vsplit")
end
if opts.mode.win.split.direction == "horizontal" then
if opts.mode.win.split.anchor == "bottom" then
vim.cmd("set splitbelow")
end
vim.cmd(opts.mode.win.split.size .. " split")
end
buf = vim.api.nvim_create_buf(false, true)
win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_buf(0, buf)
if scratch then
return buf, win
end
end
local full_cmd = type(cmd) == "table" and table.concat(cmd, " ") or cmd
vim.fn.jobstart(full_cmd, { term = true })
vim.api.nvim_buf_set_keymap(
buf,
"n",
"<ESC>",
"i<C-\\><C-n>:q<CR>",
{ noremap = true, silent = true }
)
return buf, win
end
return M
-55
View File
@@ -1,55 +0,0 @@
site_name: Polydev
nav:
- Home: index.md
- Installation: installation.md
- Setup: setup.md
- Language Specific Docs:
- Java: languages/java.md
- C: languages/c.md
- Cpp: languages/cpp.md
- Lua: languages/lua.md
- Python: languages/python.md
- Rust: languages/rust.md
- Html: languages/html.md
theme:
name: material
features:
- navigation.tabs
- navigation.sections
- toc.integrate
- navigation.top
- search.suggest
- search.highlight
- content.tabs.link
- content.code.annotation
- content.code.copy
language: en
palette:
- scheme: slate
primary: slate
accent: teal
extra:
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/DarthMooMancer
markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.inlinehilite
- pymdownx.snippets
- admonition
- pymdownx.arithmatex:
generic: true
- footnotes
- pymdownx.details
- pymdownx.superfences
- pymdownx.mark
- attr_list
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
copyright: |
&copy; 2025 <a href="https://github.com/DarthMooMancer" target="_blank" rel="noopener">DarthMooMancer</a>
+20
View File
@@ -0,0 +1,20 @@
# stylua.toml
# How many characters per line before wrapping
column_width = 100
# Indentation style: "Tabs" or "Spaces"
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 4
# Quote styling: "AutoPreferDouble", "AutoPreferSingle", "ForceDouble", "ForceSingle"
quote_style = "AutoPreferDouble"
# Call parentheses: "Always", "NoSingleString", "None", "Input"
# "None" removes parens when a single string/table literal is passed: fn "arg" / fn { ... }
# "Always" keeps them strictly standard: fn("arg") / fn({ ... })
call_parentheses = "Always"
# Sorting and formatting behavior
collapse_simple_statement = "Never"