78 Commits
Author SHA1 Message Date
DarthMooMancer 70ff086e0c Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-05-16 00:35:48 -04:00
DarthMooMancer b348710bd5 fix(docs, configs): removed build_attribues from docs and configs; removed unnecessary requirements from installation and index 2025-05-16 00:35:39 -04:00
DarthMooMancer dc0cf79188 Update README.md 2025-05-16 00:27:14 -04:00
DarthMooMancer 0ac0267888 Major Update: v1.2.0
rework: languages are in one files called languages making it easier to manage all languages and removes headache
feat: added ui in a725faaac8
2025-05-15 14:38:07 -04:00
DarthMooMancer 46263ca5e0 fix: project root is properly taken by user opts
feat: user can change border of terminal alongside enabling/disabling it
2025-05-15 11:31:11 -04:00
DarthMooMancer 28fdb698bf rework: check description
docs: removed lines about plenary
removal: plenary
chore: optmized presets load to default nil as 'max'
rework: changed window format of manager and added coloring

Future plans: Add custom highlight-groups for Polydev to configure
border and background or manager
2025-05-15 01:00:57 -04:00
DarthMooMancer 9105add777 rework: removed max preset and made it default as nil instead 2025-05-14 22:20:35 -04:00
DarthMooMancer eb3e75fe67 removal: keybinds to be added to main panel 2025-05-14 21:30:31 -04:00
DarthMooMancer def81ab3f3 Removal: center preset 2025-05-14 13:50:28 -04:00
DarthMooMancer 4d34b5d1be docs: update to setup and installation
Removing redudancy in installation at the top. Changed setup to use
names for each setting for clarity for people who don't know what is
going on
2025-05-14 13:26:04 -04:00
DarthMooMancer fa7851a787 rework: top-level project folder is now changeable and organized templates 2025-05-14 16:27:53 -04:00
DarthMooMancer 632add5f4a Update setup.md 2025-05-14 13:11:35 -04:00
DarthMooMancer 95bad52a3e Update LICENSE 2025-05-14 12:47:50 -04:00
DarthMooMancer 31929db357 Update index.md 2025-05-14 12:44:14 -04:00
DarthMooMancer e888571c63 Update installation.md 2025-05-14 11:36:36 -04:00
DarthMooMancer 645ddcab04 Update index.md 2025-05-14 11:34:29 -04:00
DarthMooMancer 2787644994 Update index.md 2025-05-14 11:34:03 -04:00
DarthMooMancer e884de149a Update index.md 2025-05-14 11:28:40 -04:00
DarthMooMancer 71c88ec956 Update README.md 2025-05-14 11:27:30 -04:00
DarthMooMancer 4c6b1289fc Update README.md 2025-05-14 11:27:11 -04:00
DarthMooMancer e8f51361ad Update README.md 2025-05-14 11:24:44 -04:00
DarthMooMancer ee73604008 Update README.md 2025-05-14 11:22:30 -04:00
DarthMooMancer cf5c7d8bbb Update README.md 2025-05-14 11:19:01 -04:00
DarthMooMancer 9c4a50da8e Update README.md 2025-05-14 11:18:28 -04:00
DarthMooMancer 2c8ae6b254 Update README.md 2025-05-14 11:17:58 -04:00
DarthMooMancer fa975c2aab feat: added compile_commands support for c/c++ when creating project 2025-05-12 18:23:41 -04:00
DarthMooMancer 88910d039b asdff 2025-05-12 11:13:37 -04:00
DarthMooMancer 75b43d31c9 fixed c/c++ build and run with error handling 2025-05-12 14:18:39 -04:00
DarthMooMancer e935cad8b7 Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-05-12 09:33:22 -04:00
DarthMooMancer b5b1cfa449 chore: removed unused guard in templates for c/c++ 2025-05-12 09:32:51 -04:00
DarthMooMancer 1306f86a65 chore: removed redundant lines in templates 2025-05-12 09:31:27 -04:00
DarthMooMancer 41e6fa1c48 Update index.md 2025-05-12 09:27:09 -04:00
DarthMooMancer 5f45ee5029 Update README.md 2025-05-12 09:24:36 -04:00
DarthMooMancer 3a50bf9375 chore: renamed open_project_manager to manager and added aux files to hints 2025-05-12 09:09:08 -04:00
DarthMooMancer 8d913ce979 docs: fixed bold for installation 2025-05-12 09:01:32 -04:00
DarthMooMancer 2d2164c380 chore: renamed open_float_terminal to terminal and annotated utils.lua 2025-05-12 08:59:02 -04:00
DarthMooMancer a2c43661c4 rework: open_float_terminal uses table instead of string
fix: all languages now use proper terminal setup
2025-05-12 08:43:42 -04:00
DarthMooMancer 4ddbe07a30 docs: update to fix .polydev mentions and improper presets 2025-05-12 02:19:54 -04:00
DarthMooMancer fe6d03981c removed: reorganized utils code because it was unused and removed
unnecessary presets_opts calls
2025-05-12 02:17:26 -04:00
DarthMooMancer 294047bcda docs: removed .polydev mentions and changed presets names
fix: presets had improper variable names on call
fix: java now builds properly and runs
2025-05-12 02:12:55 -04:00
DarthMooMancer b07b2aec9d fix: made preset names more simple to understand 2025-05-12 01:38:33 -04:00
DarthMooMancer c6ea4f4f89 rework: removed old get functions from each language to use utils
instead and changed run in each language to use new system to be simpler

feat: added aux_files for c/c++ and reworked them to work with new
update
2025-05-12 01:27:46 -04:00
DarthMooMancer 8584ed4bbf rework: templates.files uses table instead of deprecated string format
rework: templates.files no longer requires the deprecated .polydev files
feat: added get_project_name to utils
2025-05-12 01:09:03 -04:00
DarthMooMancer 4ecaf54f82 refactor: fixed deprecated write_file to use table instead of string for
each language in templates.projects
2025-05-12 00:41:05 -04:00
DarthMooMancer 677e5bbc67 fix: fixed git initialization for project
chore: change write_file to take table instead of string
2025-05-11 14:19:49 -04:00
DarthMooMancer 674dd47dbc cleanup: removed unnecessary files 2025-05-11 09:09:11 -04:00
DarthMooMancer 1e987bf5b6 feat: added git initalization to java as test for replacement to polydev files 2025-05-11 09:07:03 -04:00
DarthMooMancer acb859f9e5 Add walkup for now 2025-05-11 15:38:57 -04:00
DarthMooMancer 734b60f145 feat: added ui.lua to cleanup init.lua
chore: optimized keybind setup in init.lua
2025-05-08 09:22:47 -04:00
DarthMooMancer 34aa8346e9 chore: changed presets to preset for config and updated docs 2025-05-08 08:47:04 -04:00
DarthMooMancer 96378ec33d fix: readded build_attributes to c because I forgot I removed it 2025-05-08 08:31:46 -04:00
DarthMooMancer 6c53a052b3 docs: update to languages to contain proper information and added (Html,
Rust)
2025-05-08 08:30:29 -04:00
DarthMooMancer 368a5d98f8 chore: organized and optimized startup
docs: updated documentation to be simpler and up to date
2025-05-08 00:35:37 -04:00
DarthMooMancer 15913c75b7 FIX: fixed lua to not use global function but local to stop nil error 2025-05-07 11:31:49 -04:00
DarthMooMancer 20a375aaf5 chore: cleaned up cpp.lua to find polydev file faster and cleaned up
configs file
2025-05-07 11:11:17 -04:00
DarthMooMancer cac1fdb02c docs: removed warning from c files about early build issues 2025-05-07 10:45:21 -04:00
DarthMooMancer bb9efdbd8a REMOVED: padding options from default options in configs.lua 2025-05-02 10:52:34 -04:00
DarthMooMancer bbb1e0c24a FIX: Changed naming convention to be the same throughout the presets
file and fixed neovim api for temrinal.

Update: Changed how presets are made to be simpler
2025-05-02 10:46:07 -04:00
DarthMooMancer ff360658e4 FIX: Changed terminal to use new vim api as neovim deprecated old 2025-05-01 22:00:09 -04:00
DarthMooMancer 908cb7ae03 fix: cleaned up hint popup page for simplicity 2025-05-01 09:26:49 -04:00
DarthMooMancer 9aedf18379 Removed: vcpkg cmake creation, will readd somehow later 2025-04-30 12:58:36 -04:00
DarthMooMancer cbaf74418b Added gitignore creation for c++ 2025-04-30 12:55:41 -04:00
DarthMooMancer e2ebe918bd Changes and fixes to c++ project creation 2025-04-25 09:04:59 -04:00
DarthMooMancer 546d204f9d Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-04-23 14:50:25 -04:00
DarthMooMancer 534dc2819e Update to documentation, update with merging run and build commands, cleaned up and organized the project manager 2025-04-23 14:50:17 -04:00
DarthMooMancer 5449c2a9f3 Update README.md 2025-04-21 05:21:37 -04:00
DarthMooMancer 9db6059fb7 Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-04-21 05:19:54 -04:00
DarthMooMancer a725faaac8 added project manager and updated documentation 2025-04-21 05:19:27 -04:00
DarthMooMancer c70246818e Update mkdocs.yml 2025-04-21 01:56:29 -04:00
DarthMooMancer 3db95f1b7c Update ci.yml 2025-04-21 01:55:39 -04:00
DarthMooMancer 467d864eb4 Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-04-21 01:53:27 -04:00
DarthMooMancer 919a856d93 Update to mkdocs 2025-04-21 01:53:19 -04:00
DarthMooMancer cb476fa5ec Update ci.yml 2025-04-21 01:46:37 -04:00
DarthMooMancer f5b59c0f95 Update ci.yml 2025-04-21 01:41:28 -04:00
DarthMooMancer e28bcc41ea Added presets and updated documentation 2025-04-21 01:35:57 -04:00
DarthMooMancer 8425a838d0 Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-04-18 23:55:00 -04:00
DarthMooMancer 71bc395125 Added Presets for terminal placements 2025-04-18 23:54:43 -04:00
DarthMooMancer b6640dfcee Update README.md 2025-04-18 10:52:51 -04:00
31 changed files with 1310 additions and 1277 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
*.polydev
LICENSE LICENSE
Lua_Annotation_CheatSheet/ Lua_Annotation_CheatSheet/
venv/
+197 -17
View File
@@ -1,21 +1,201 @@
MIT License Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Copyright (c) 2025 DarthMooMancer TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Permission is hereby granted, free of charge, to any person obtaining a copy 1. Definitions.
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:
The above copyright notice and this permission notice shall be included in all "License" shall mean the terms and conditions for use, reproduction,
copies or substantial portions of the Software. and distribution as defined by Sections 1 through 9 of this document.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR "Licensor" shall mean the copyright owner or entity authorized by
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, the copyright owner that is granting the License.
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER "Legal Entity" shall mean the union of the acting entity and all
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, other entities that control, are controlled by, or are under common
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE control with that entity. For the purposes of this definition,
SOFTWARE. "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.
View File
+39 -35
View File
@@ -1,56 +1,60 @@
# **Polydev** 🌐 <h1 align="center">Polydev</h1>
**Polydev** is a powerful multi-lingual plugin for Neovim that streamlines project management, file creation, building, and running code—all within your favorite terminal editor. Whether you're coding in Java, Python, Lua, Rust, or more, Polydev brings seamless integration and enhanced productivity right to your fingertips. <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>
![Polydev-c](https://github.com/user-attachments/assets/365dd673-6b1f-4ccc-ac1f-c5131d055fd9) <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" />
</p>
--- <p align="center">
<img src="https://github.com/user-attachments/assets/c8e84056-5080-4ec3-ba15-30be61faaf68" alt="Polydev Preview" width="720"/>
</p>
## 🚀 **Quick Features** ## Features
Polydev helps you work smarter, not harder. With this plugin, you can: * Create and manage 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
- 📂 **Create New Projects**: Start fresh with ease. > 📚 [View the full documentation](https://darthmoomancer.github.io/Polydev/) for setup, configuration, and usage details.
- 📝 **Generate New Files**: Add files to your projects with just a few keystrokes.
- ⚙️ **Build Your Files**: Compile and prepare your projects directly within Neovim.
- 🎮 **Run Your Code**: Execute your code and see results without leaving your terminal.
- 🖥️ **Built-in Terminal**: A terminal integrated directly into Neovim for running commands, scripts, or code.
- 🌱 **More to Come**: Ongoing development means new features and improvements are always on the horizon!
**Need more info?** Check out the full [Polydev Documentation](https://darthmoomancer.github.io/Polydev/) for setup instructions, configurations, and usage details.
--- ## Supported Languages
## ✅ **Currently Supported (And Working) Languages** Polydev currently supports the following languages:
Polydev supports a wide range of languages, providing a smooth development experience: * Java
* Python
* C / C++
* Lua
* Rust
* HTML
- **Java** ☕️ Additional language support is planned for future releases.
- **Python** 🐍
- **C/C++** 💻
- **Lua** 🐢
- **Rust** 🦀
- **HTML** 🌍
And more on the way! Stay tuned for future updates.
--- ## Roadmap
## 🔮 **Planned Features** Current focus:
* **Refactoring and internal cleanup.**
We're always working to make Polydev better. Here’s a sneak peek at some exciting plans: Feature additions will resume after this phase.
- 🚀 **Rust Integration**: Leverage Rust to speed up certain aspects of the plugin for faster performance and better scalability.
--- ## Contributing
## 🤝 **Questions and Contributing** Contributions are welcome and appreciated.
Got ideas? 💡 Have a feature you’d love to see or a language you want to see supported? Your contributions are always welcome! Here's how you can get involved: * Open an issue for bug reports, questions, or feature requests.
* Submit a pull request if you'd like to contribute directly.
- 🔧 **Contribute**: Open a Pull Request (PR) or create an issue with your suggestions or bug reports.
- 💬 **Ask Questions**: If you're stuck or have questions, drop them in the issues or discussions section, and I'll get back to you as soon as I can.
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 Polydev even better! Thank you for being part of the journey. 🙏
---
+18
View File
@@ -0,0 +1,18 @@
#!/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"
+50 -36
View File
@@ -1,56 +1,70 @@
# 🚀 Welcome to Polydev <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>
Polydev is a highly customizable and extensible Neovim plugin aimed at streamlining project creation and management for multiple programming languages. It’s especially suited for developers who work across different languages and want a consistent workflow for initializing, building, and running projects. <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>
![Polydev-c](https://github.com/user-attachments/assets/365dd673-6b1f-4ccc-ac1f-c5131d055fd9) <p align="center">
<img src="https://github.com/user-attachments/assets/c8e84056-5080-4ec3-ba15-30be61faaf68" alt="Polydev Preview" width="720"/>
</p>
## ❓ What is Polydev?
Polydev is designed to be a centralized workspace tool that reduces repetitive tasks involved in setting up development environments. Whether you’re working on a Lua plugin, a Rust CLI tool, or a C++ project, Polydev helps you scaffold project directories, create boilerplate code, and define keybinds to streamline execution — all from within Neovim. ## **Why Polydev**?
## 💡 Why Polydev? Working across multiple languages often means repetitive setup and constant context switching. Polydev eliminates this friction by offering:
Modern development often involves juggling multiple languages. Setting up similar environments repeatedly or manually running commands wastes time. Polydev solves this by providing: * Project templates per language
* Custom keybindings for essential actions
* Floating terminal integration
* Automated file and folder generation
* A plugin-first design for easy extensibility
- 📦 **Project templates per language**
- 🎯 **Custom keybindings for common actions**
- 💻 **Floating terminal support**
- 🗂 **Easy file creation and directory structure generation**
- 🔌 **Plugin-first architecture to expand functionality**
## 🔧 Core Features ## **Core Features**
- 🌐 **Language Support**: Define custom settings per language including `project_root`, `keybinds`, and `build_attributes`. * **Language Profiles**
- 🪟 **Floating Terminals**: Run builds and executions in a Neovim floating terminal. Define settings per language including `project_root`, keymaps, and build commands.
- 🧱 **Scaffolding**: Automatically create the appropriate directory and file layout for new projects.
- 🎹 **Keybind Mapping**: Rebind keys to execute project-specific commands like `Build`, `Run`, or `Test`.
- 🔌 **Pluggable**: Designed to easily integrate with other tools or extend with your own commands and language presets.
## 👥 Target Audience * **Floating Terminals**
Run build, and run commands in a clean, isolated terminal window inside Neovim.
Polydev is perfect for: * **Scaffolding**
Quickly generate boilerplate and structured directories for new projects.
- 🧑‍💻 Developers building across multiple languages * **Custom Keybinds**
- 🔌 Plugin authors and power users of Neovim Map actions like `Run`, `PipInstall`, `Open Manager`, `etc` to your preferred keys.
- ⚡ Anyone who wants automated project bootstrapping
## 🎯 Goals * **Pluggable Design**
Easily extend functionality with custom language presets and commands.
- 📏 **Consistency**: Provide a common interface for all your dev projects.
- 🧩 **Extensibility**: Let users add their own languages and tools.
- ✨ **Simplicity**: Reduce boilerplate and context switching.
## 🧪 Example Use Case ## **Who It's For**
Say you're a developer who works with Rust, Lua, and Python. Instead of remembering build commands, directory structures, or manually creating a `main.rs` or `init.lua`, Polydev: * Developers who work in multiple languages
* Neovim plugin authors or power users
* Anyone who wants a faster, more unified project workflow
1. 🏗 Sets up your directory based on language conventions.
2. 📄 Generates boilerplate files.
3. 🎛 Maps `<leader>pr` to `Run`, `<leader>pb` to `Build`, and so on.
4. 🖥 Opens a floating terminal to show your output.
## 🏷 Versioning ## **Design Goals**
Polydev uses GitHub tags and branches to manage plugin versions. Each version corresponds to a stable release that users can track. * **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.
+18 -102
View File
@@ -1,127 +1,43 @@
# 📦 Installation ## **Lazy.nvim**
Polydev can be installed using any plugin manager of your choice—or even manually. Below are some examples for popular managers to get you started.
> ⚠️ **Disclaimer**: The `opts` and configuration values shown below are simply examples. You can customize them based on your preferences or even omit them entirely if not needed.
> 💡 **Heads up!** Many language presets in Polydev require a file named `<project_name>.polydev` in your project root. If it's missing, Polydev will let you know (loudly 😅).
---
## 🛌 Lazy.nvim
This is the **recommended** way if you're using [Lazy.nvim](https://github.com/folke/lazy.nvim):
```lua ```lua
{ return {
"DarthMooMancer/Polydev", "DarthMooMancer/Polydev",
opts = { dependencies = {
lua = { "MunifTanjim/nui.nvim"
project_root = "~/Projects/Lua",
keybinds = {
["<leader>pr"] = "LuaRun",
},
},
terminal = {
border = true,
number = true,
},
}, },
opts = {}, -- Setup is later on
} }
``` ```
> ✅ Keep the `opts` key! It’s the modern way of setting up plugins in Lazy.
--- ---
## 🧸 Mini.deps ## **Mini.deps**
For users of [mini.nvim](https://github.com/echasnovski/mini.nvim)'s dependency manager:
```lua ```lua
MiniDeps.add({ source = "DarthMooMancer/Polydev" }) MiniDeps.add({
source = "DarthMooMancer/Polydev"
require("Polydev").setup({ depends = {
rust = { "MunifTanjim/nui.nvim"
project_root = "~/Projects/Rust", }
keybinds = {
["<leader>pb"] = "RustBuild",
["<leader>pr"] = "RustRun",
},
},
terminal = {
border = true,
number = true,
},
}) })
require("Polydev").setup({})
``` ```
--- ---
## 📁 Packer.nvim ## **Packer.nvim**
For fans of [Packer.nvim](https://github.com/wbthomason/packer.nvim):
```lua ```lua
use({ use({
"DarthMooMancer/Polydev", "DarthMooMancer/Polydev",
config = function() requires = {
require("Polydev").setup({ "MunifTanjim/nui.nvim"
python = {
project_root = "~/Projects/Python",
keybinds = {
["<leader>pb"] = "PythonPip",
["<leader>pr"] = "PythonRun",
}, },
},
terminal = {
relativenumber = true,
},
})
end,
}) })
require("Polydev").setup({})
``` ```
--- ---
## 🔐 Vim-Plug (Classic)
Even if you're still using [vim-plug](https://github.com/junegunn/vim-plug), you’re covered:
```vim
Plug 'DarthMooMancer/Polydev'
lua << EOF
require("Polydev").setup({
c = {
project_root = "~/Projects/C",
keybinds = {
["<leader>pb"] = "CBuild",
["<leader>pr"] = "CRun",
},
},
terminal = {
number = true,
},
})
EOF
```
---
## 🛠 Manual Install
Clone the repo into your `~/.config/nvim/lua` or any runtime path:
```bash
git clone https://github.com/DarthMooMancer/Polydev ~/.config/nvim/lua/Polydev
```
Then in your config:
```lua
require("Polydev").setup({
terminal = {
border = true,
},
})
```
+2 -33
View File
@@ -1,33 +1,3 @@
### C Setup for Polydev 🛠️
#### Key Notes ⚠️
> **Important**: The first time you build a project, it might throw an error. This is expected behavior. Simply rerun the build, and if errors persist, it may be an issue with your project setup rather than the plugin.
---
#### Keybinds 🎮
You can customize keybinds for your C projects with Polydev.
| Keybind | Action |
|---------------------|--------------------------------------------------|
| `<leader>pb` | Build all C files in the `src` directory |
| `<leader>pr` | Run `<Project_name>` in your build directory |
| `<leader>nh` | Create a new header file in the current project’s `src` folder |
#### Configuration Example:
```lua
require("Polydev").c.setup({
keybinds = {
["<leader>pb"] = "CBuild", -- Build all C files in the src directory
["<leader>pr"] = "CRun", -- Run <Project_name> in your build directory
["<leader>nh"] = "NewCHeaderFile" -- Create a new header file in the current project’s src folder
}
})
```
---
#### File Structure 📂 #### File Structure 📂
This is the recommended file structure for your C projects using Polydev: This is the recommended file structure for your C projects using Polydev:
@@ -38,7 +8,6 @@ This is the recommended file structure for your C projects using Polydev:
| `main.c` | Main C file for the project | | `main.c` | Main C file for the project |
| `*.c` | Additional C source files | | `*.c` | Additional C source files |
| `build/` | Folder where the build artifacts will be generated | | `build/` | Folder where the build artifacts will be generated |
| `<project_name>.polydev` | Polydev metadata file (generated during build) |
| `include/` | Folder for header files | | `include/` | Folder for header files |
| `*.h` | C header files | | `*.h` | C header files |
@@ -53,9 +22,9 @@ Projects/
│ ├── main.c │ ├── main.c
│ └── *.c │ └── *.c
├── build/ ├── build/
│ └── <project_name>.polydev │ └── <CMAKE_FILES>
│ └── <main-executable>
└── include/ └── include/
└── *.h └── *.h
``` ```
--- ---
+2 -32
View File
@@ -1,33 +1,3 @@
### C Setup for Polydev 🛠️
#### Key Notes ⚠️
> **Important**: The first time you build a project, it might throw an error. This is expected behavior. Simply rerun the build, and if errors persist, it may be an issue with your project setup rather than the plugin.
---
#### Keybinds 🎮
You can customize keybinds for your C projects with Polydev.
| Keybind | Action |
|---------------------|--------------------------------------------------|
| `<leader>pb` | Build all C files in the `src` directory |
| `<leader>pr` | Run `<Project_name>` in your build directory |
| `<leader>nh` | Create a new header file in the current project’s `src` folder |
#### Configuration Example:
```lua
require("Polydev").c.setup({
keybinds = {
["<leader>pb"] = "CppBuild", -- Build all C files in the src directory
["<leader>pr"] = "CppRun", -- Run <Project_name> in your build directory
["<leader>nh"] = "NewCppHeaderFile" -- Create a new header file in the current project’s src folder
}
})
```
---
#### File Structure 📂 #### File Structure 📂
This is the recommended file structure for your C projects using Polydev: This is the recommended file structure for your C projects using Polydev:
@@ -38,7 +8,6 @@ This is the recommended file structure for your C projects using Polydev:
| `main.cpp` | Main Cpp file for the project | | `main.cpp` | Main Cpp file for the project |
| `*.cpp` | Additional Cpp source files | | `*.cpp` | Additional Cpp source files |
| `build/` | Folder where the build artifacts will be generated | | `build/` | Folder where the build artifacts will be generated |
| `<project_name>.polydev` | Polydev metadata file (generated during build) |
| `include/` | Folder for header files | | `include/` | Folder for header files |
| `*.hpp` | Cpp header files | | `*.hpp` | Cpp header files |
@@ -53,7 +22,8 @@ Projects/
│ ├── main.cpp │ ├── main.cpp
│ └── *.cpp │ └── *.cpp
├── build/ ├── build/
│ └── <project_name>.polydev │ └── <CMAKE_FILES>
│ └── <main-executable>
└── include/ └── include/
└── *.hpp └── *.hpp
``` ```
+1
View File
@@ -0,0 +1 @@
Nothing here yet! Html is supported however!
+2 -28
View File
@@ -1,30 +1,4 @@
### Java Setup for Polydev ☕️ ### **Java Features**
#### Keybinds 🎮
You can customize the keybinds for your Java projects in Polydev.
| Keybind | Action |
|---------------------|-----------------------------------------------------|
| `<leader>pb` | Build all Java files in the `src` directory |
| `<leader>pr` | Run `Main.java` from the `out` folder in your project |
| `<leader>nf` | Create a new Java file in the `src` folder |
#### Configuration Example:
```lua
-- These are defaults, so no need to copy them
require("Polydev").java.setup({
keybinds = {
["<leader>pb"] = "JavaBuild", -- Build all Java files in the src directory
["<leader>pr"] = "JavaRun", -- Run Main.java in the out folder
["<leader>nf"] = "NewJavaFile" -- Create a new Java file in the src folder
}
})
```
---
#### Java Features ✨
* **Java Build and Run**: * **Java Build and Run**:
Polydev allows you to build all Java files in the `src` directory with the press of a keybind. Once built, you can run the project from the `out` folder, with the `Main.java` file executed automatically. Polydev allows you to build all Java files in the `src` directory with the press of a keybind. Once built, you can run the project from the `out` folder, with the `Main.java` file executed automatically.
@@ -34,7 +8,7 @@ require("Polydev").java.setup({
--- ---
#### File Structure 📂 #### File Structure
Here’s the recommended structure for your Java projects using Polydev: Here’s the recommended structure for your Java projects using Polydev:
| Directory/File Path | Description | | Directory/File Path | Description |
+1 -34
View File
@@ -1,35 +1,4 @@
### Lua Setup for Polydev 🐢 ### **Lua Features**
#### Key Notes ⚠️
* Polydev provides seamless integration with Lua projects, allowing you to easily run and manage Lua code.
* You must include a `<Project_name>.polydev` file in your project root directory for Polydev to recognize the project. Missing this file will lead to errors.
* The file structure should be organized to ensure smooth execution and functionality.
---
#### Keybinds 🎮
Below are the default keybinds for Lua projects using Polydev. You can adjust them to suit your personal preferences.
| Keybind | Action |
|---------------------|-------------------------------------------------|
| `<leader>pr` | Run the Lua project |
##### Configuration Example:
```lua
-- These are the defaults for Lua, adjust as needed
require("Polydev").lua.setup({
keybinds = {
["<leader>pr"] = "LuaRun", -- Run the Lua project
}
})
```
---
#### Lua Features ✨
* **Run Lua Projects**: * **Run Lua Projects**:
Easily run your Lua project from within your terminal using the `<leader>pr` keybind. This automatically runs your `init.lua` or the entry point of your Lua code. Easily run your Lua project from within your terminal using the `<leader>pr` keybind. This automatically runs your `init.lua` or the entry point of your Lua code.
@@ -45,7 +14,6 @@ Here’s the suggested directory structure for your Lua projects with Polydev:
| Directory/File Path | Description | | Directory/File Path | Description |
|----------------------------|-----------------------------------------------------| |----------------------------|-----------------------------------------------------|
| `<Project_name>.polydev` | Project metadata file that Polydev uses for configuration |
| `lua/` | Directory containing the main Lua project files | | `lua/` | Directory containing the main Lua project files |
| `lua/<Project_name>/init.lua` | The main entry point for your Lua project | | `lua/<Project_name>/init.lua` | The main entry point for your Lua project |
@@ -55,7 +23,6 @@ Here’s the suggested directory structure for your Lua projects with Polydev:
Projects/ Projects/
└── Lua/ └── Lua/
└── Project_Name/ └── Project_Name/
├── <Project_name>.polydev -- Polydev configuration file
└── lua/ └── lua/
└── Project_name/ └── Project_name/
└── init.lua -- Main Lua file └── init.lua -- Main Lua file
+3 -26
View File
@@ -1,27 +1,4 @@
### Python Setup for Polydev 🐍 ### **Python Features**
#### Keybinds 🎮
You can easily customize the keybinds for your Python projects using Polydev.
| Keybind | Action |
|---------------------|---------------------------------------------------|
| `<leader>pr` | Run the Python project in your active terminal |
| `<leader>pb` | Install dependencies using pip |
#### Configuration Example:
```lua
require("Polydev").python.setup({
keybinds = {
["<leader>pr"] = "PythonRun", -- Run the Python project
["<leader>pb"] = "PythonPip" -- Install dependencies using pip
}
})
```
---
#### Python Features 🚀
Here are some cool features available for Python projects using Polydev: Here are some cool features available for Python projects using Polydev:
@@ -36,7 +13,7 @@ You no longer need to manually activate or deactivate virtual environments. With
--- ---
#### File Structure 📂 #### **File Structure**
Here’s the recommended structure for your Python projects using Polydev: Here’s the recommended structure for your Python projects using Polydev:
| Directory/File Path | Description | | Directory/File Path | Description |
@@ -47,7 +24,7 @@ Here’s the recommended structure for your Python projects using Polydev:
| `venv/` | Virtual environment folder | | `venv/` | Virtual environment folder |
| `main.py` | Main Python file for your project | | `main.py` | Main Python file for your project |
#### Example Structure: #### **Tree Structure**:
```md ```md
Projects/ Projects/
+1
View File
@@ -0,0 +1 @@
Nothing here yet! Rust is supported however!
+111 -120
View File
@@ -1,136 +1,127 @@
## **Project Manager**
> Note: The project manager closely follows the netrw keybinds and allows for project management all in one spot
# Setup and Customizing Polydev | 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` |
## 🔧 Project Name Customization > **WARNING**: Do not copy the defaults. Only change what you need for your workflow!
You can easily customize the default directory for your project! The project can be created from any directory, and Polydev will automatically create the required project root directory for you.
> **Note:** `project_root` allows you to customize where your project will be stored. If you don't specify it, the default is `~/Projects/Language`.
---
### LazyVim Example
## **Project Root**
```lua ```lua
return { -- Automatically creates a project root if not already made.
... -- Stores all projects in this root
opts = {
<language> = { -- Global --
project_root = "~/Home/..." -- Default: ~/Projects/Language 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"
} }
``` ```
### Packer Example ## **Keybinds**
```lua ```lua
require("Polydev").language.setup({ -- globals --
project_root = "~/Home/..." -- Default: ~/Projects/Language globals = {
})
```
## ⌨ Keybinds Customization
Polydev allows you to easily manage keybinds, providing a uniform way to interact with different languages. Most keybinds are the same across languages, while some have language-specific ones (e.g., Python's pip keybind).
### Keybind Categories
| Keybind Type | Description |
|-------------------|--------------------------------------------------|
| **Universal** | Cannot be changed through specific language settings (e.g., `<leader>nf` for a new file). |
| **Per-language** | Can be customized per language (e.g., `<leader>pb` for language build). |
### LazyVim Example
```lua
return {
...
opts = {
<language> = {
["<Esc>"] = "CloseTerminal", -- Universal, can be changed per language for now
["<leader>pb"] = "languageBuild", -- Per-language
["<leader>pr"] = "languageRun", -- Per-language
["<leader>nf"] = "NewLanguageFile", -- Universal
["<leader>nh"] = "NewLanguageSecondaryFile", -- Universal
}
}
...
}
```
### Packer Example
```lua
require("Polydev").language.setup({
keybinds = { keybinds = {
["<Esc>"] = "CloseTerminal", -- Universal, can be changed per language for now ["<leader>po"] = "PolydevManager",
["<leader>pb"] = "languageBuild", -- Per-language
["<leader>pr"] = "languageRun", -- Per-language
["<leader>nf"] = "NewLanguageFile", -- Universal
["<leader>nh"] = "NewLanguageSecondaryFile", -- Universal
} }
}) }
-- 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**
## 🖥 Terminal Customization
You can further tweak the terminal settings to suit your preferences! These options allow you to adjust padding, borders, numbers, and scrolling behavior.
### Available Terminal Settings
| Setting | Default Value | Description |
|------------------|-----------------|---------------------------------------------------------|
| **right_padding** | `0` | Padding for the right width of the terminal. |
| **left_padding** | `0` | Padding for the left width of the terminal. |
| **top_padding** | `0` | Padding for the top height of the terminal. |
| **bottom_padding**| `0` | Padding for the bottom height of the terminal. |
| **border** | `true` | Adds a rounded border to the window. |
| **number** | `true` | Displays line numbers in the terminal. |
| **relativenumber**| `true` | Displays relative numbers based on cursor position. |
| **scroll** | `true` | Enables scroll functionality in the terminal. |
> **Note:** These terminal settings allow you to personalize the terminal view and improve usability. You can easily adjust the padding, borders, and other aspects to your preference.
---
### LazyVim Example
```lua ```lua
return { -- In Neovim 0.11+, numbers don't work so they will be reimplemented later
... terminal = {
opts = { preset = nil, -- also try : ("right", "corner")
terminal = { border = true
right_padding = 0,
bottom_padding = 0,
left_padding = 0,
top_padding = 0,
border = true,
number = true,
relativenumber = true,
scroll = true,
}
}
...
} }
``` ```
### Packer Example
```lua
require("Polydev").setup({
terminal = {
right_padding = 0,
bottom_padding = 0,
left_padding = 0,
top_padding = 0,
border = true,
number = true,
relativenumber = true,
scroll = true,
}
})
```
## 🚀 Final Thoughts and Customizations
This guide provided you with the basic configuration steps for setting up Polydev with your preferred package manager and customizing key aspects like project names, keybinds, and terminal settings.
You can further explore other Polydev features and modify the configuration to suit your development workflow.
+36 -63
View File
@@ -1,107 +1,80 @@
---@type table
local M = {} local M = {}
---@class KeybindConfigs
---@field [string] string
---
---@class LanguageConfigs
---@field project_root? string
---@field keybinds? KeybindConfigs -- ? makes fields optional
---@field build_attributes? string
---
---@class TerminalConfigs
---@field right_padding integer
---@field left_padding integer
---@field bottom_padding integer
---@field top_padding integer
---@field border boolean
---@field number boolean
---@field relativenumber boolean
---
---@class Defaults
---@field html LanguageConfigs
---@field rust LanguageConfigs
---@field java LanguageConfigs
---@field python LanguageConfigs
---@field lua LanguageConfigs
---@field c LanguageConfigs
---@field cpp LanguageConfigs
---@field terminal TerminalConfigs
---@type Defaults
M.defaults = { M.defaults = {
html = { globals = {
project_root = "~/Projects/Html", project_root = "~/Projects",
keybinds = {
["<leader>po"] = "PolydevManager",
}, },
},
terminal = {
preset = nil,
border = {
enabled = true,
type = "rounded",
},
},
}
local function default_languages(project_root)
return {
rust = { rust = {
project_root = "~/Projects/Rust", project_root = project_root .. "/Rust",
keybinds = { keybinds = {
["<leader>pb"] = "RustBuild",
["<leader>pr"] = "RustRun", ["<leader>pr"] = "RustRun",
}, },
}, },
java = { java = {
project_root = "~/Projects/Java", project_root = project_root .. "/Java",
keybinds = { keybinds = {
["<leader>pb"] = "JavaBuild",
["<leader>pr"] = "JavaRun", ["<leader>pr"] = "JavaRun",
}, },
}, },
python = {
project_root = "~/Projects/Python",
keybinds = {
["<leader>pr"] = "PythonRun",
["<leader>pb"] = "PythonPip",
},
},
lua = { lua = {
project_root = "~/Projects/Lua", project_root = project_root .. "/Lua",
keybinds = { keybinds = {
["<leader>pr"] = "LuaRun", ["<leader>pr"] = "LuaRun",
}, },
}, },
c = { c = {
project_root = "~/Projects/C", project_root = project_root .. "/C",
keybinds = { keybinds = {
["<leader>pb"] = "CBuild",
["<leader>pr"] = "CRun", ["<leader>pr"] = "CRun",
["<leader>nh"] = "NewCHeaderFile",
}, },
build_attributes = ""
}, },
cpp = { cpp = {
project_root = "~/Projects/Cpp", project_root = project_root .. "/CPP",
keybinds = { keybinds = {
["<leader>pb"] = "CppBuild",
["<leader>pr"] = "CppRun", ["<leader>pr"] = "CppRun",
["<leader>nh"] = "NewCppHeaderFile",
}, },
build_attributes = "",
}, },
terminal = { html = {
right_padding = 0, project_root = project_root .. "/Html",
bottom_padding = 0, },
left_padding = 0,
top_padding = 0,
border = true,
number = true,
relativenumber = true,
} }
} end
---@type string[]
M.user_config = {} M.user_config = {}
---@param user_opts table ---@param user_opts table
function M.setup(user_opts) function M.setup(user_opts)
-- First merge global and terminal
M.user_config = vim.tbl_deep_extend("force", {}, M.defaults, user_opts or {}) 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 end
---@param lang string ---@param lang string
---@return string|table ---@return table
function M.get(lang) function M.get(lang)
return M.user_config[lang] or {} return M.user_config[lang] or {}
end end
---@return table
return M return M
+13 -65
View File
@@ -1,81 +1,29 @@
---@module "Polydev.configs"
local config = require("Polydev.configs")
---@module "Polydev.utils"
local utils = require("Polydev.utils")
---@module "Polydev.templates"
local templates = require("Polydev.templates")
---@type table
local M = {} local M = {}
---@type table
M.loaded_languages = {}
---@param lang string
---@param opts table?
---@return boolean
function M.load_language_module(lang, opts)
if M.loaded_languages[lang] then return true end
local ok, lang_module = pcall(require, "Polydev.languages." .. lang)
if ok and lang_module.setup then
local lang_opts = opts and opts[lang] or {}
lang_module.setup(lang_opts)
M.loaded_languages[lang] = lang_module
return true
end
return false
end
function M.create_project()
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", {}, config.get(lang), opts or {})
if M.load_language_module(lang) and templates.projects[lang] and templates.projects[lang].run then
templates.create_project(lang, opts.project_root)
else
print("Error: No project creation method for " .. lang)
end
end)
end
function M.create_new_file()
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
templates.create_new_file(lang)
else
print("Error: No File creation method for " .. lang)
end
end)
end
---@param opts table
function M.setup(opts) function M.setup(opts)
opts = opts or {} local config = require("Polydev.configs")
local ui = require("Polydev.ui")
config.setup(opts) config.setup(opts)
utils.setup(opts) require("Polydev.utils").setup(opts)
for lang, user_opts in pairs(opts) do for lang, user_opts in pairs(opts) do
local default = config.defaults[lang] or {} config.user_config[lang] = vim.tbl_deep_extend("force", config.defaults[lang] or {}, user_opts)
config.user_config[lang] = vim.tbl_deep_extend("force", default, 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 end
vim.api.nvim_create_user_command("NewProject", M.create_project, {})
vim.api.nvim_create_user_command("NewFile", M.create_new_file, {})
vim.keymap.set("n", "<leader>np", ":NewProject<CR>", { silent = true })
vim.keymap.set("n", "<leader>nf", ":NewFile<CR>", { silent = true })
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
pattern = "*", pattern = "*",
callback = function() callback = function()
local filetype = vim.bo.filetype local filetype = vim.bo.filetype
M.load_language_module(filetype, opts) ui.load_language_module(filetype, opts)
end, end,
}) })
end end
---@return table
return M return M
+174
View File
@@ -0,0 +1,174 @@
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
-82
View File
@@ -1,82 +0,0 @@
local utils = require("Polydev.utils")
local M = {}
M.keybinds = {}
M.opts = nil
function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("c"), opts or {})
for key, command in pairs(M.opts.keybinds) do
M.keybinds[command] = key
end
vim.api.nvim_create_user_command("NewCHeaderFile", M.create_new_header_file, {})
vim.api.nvim_create_user_command("CBuild", M.build, {})
vim.api.nvim_create_user_command("CRun", M.run, {})
if M.keybinds.CBuild then
vim.keymap.set("n", M.keybinds.CBuild, ":CBuild<CR>", { silent = true })
end
if M.keybinds.CRun then
vim.keymap.set("n", M.keybinds.CRun, ":CRun<CR>", { silent = true })
end
if M.keybinds.NewCHeaderFile then
vim.keymap.set("n", M.keybinds.NewCHeaderFile, ":NewCHeaderFile<CR>", { silent = true })
end
end
function M.create_new_header_file()
vim.ui.input({ prompt = "Enter header file name: " }, function(header_name)
if not header_name then return print("Header file creation canceled.") end
local root_dir = M.get_project_root()
if not root_dir then return print("Error: Project root not found.") end
local guard_macro = header_name:upper():gsub("[^A-Z0-9]", "_") .. "_H"
local content = string.format([[
#ifndef %s
#define %s
#include <stdio.h>
// Function prototypes
void example_function();
#endif // %s
]], guard_macro, guard_macro, guard_macro)
utils.write_file(root_dir .. "/include/" .. header_name .. ".h", content)
end)
end
function M.get_project_root()
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/src") == 1 or vim.fn.filereadable(dir .. "/CMakeLists.txt") == 1 then
return dir
end
dir = vim.fn.fnamemodify(dir, ":h")
end
end
function M.build()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
local build_dir = root .. "/build"
local cmd = "cd " .. build_dir .. " && cmake --build ."
local term_buf = utils.open_float_terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.list_extend({ success and "Compilation successful!" or "Error during compilation:" }, vim.split(output, "\n", { trimempty = true })))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
function M.run()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
local build_dir = root .. "/build"
local files = vim.fn.glob(build_dir .. "/*.polydev", true, true)
if #files == 0 then return print("Error: No .polydev file found in build directory.") end
utils.open_float_terminal("cd " .. build_dir .. " && ./" .. files[1]:match("([^/]+)%.polydev$"))
end
return M
-82
View File
@@ -1,82 +0,0 @@
local utils = require("Polydev.utils")
local M = {}
M.keybinds = {}
M.opts = nil
function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("cpp"), opts or {})
for key, command in pairs(M.opts.keybinds) do
M.keybinds[command] = key
end
vim.api.nvim_create_user_command("NewCppHeaderFile", M.create_new_header_file, {})
vim.api.nvim_create_user_command("CppBuild", M.build, {})
vim.api.nvim_create_user_command("CppRun", M.run, {})
if M.keybinds.CppBuild then
vim.keymap.set("n", M.keybinds.CppBuild, ":CppBuild<CR>", { silent = true })
end
if M.keybinds.CppRun then
vim.keymap.set("n", M.keybinds.CppRun, ":CppRun<CR>", { silent = true })
end
if M.keybinds.NewCppHeaderFile then
vim.keymap.set("n", M.keybinds.NewCppHeaderFile, ":NewCppHeaderFile<CR>", { silent = true })
end
end
function M.create_new_header_file()
vim.ui.input({ prompt = "Enter header file name: " }, function(header_name)
if not header_name then return print("Header file creation canceled.") end
local root_dir = M.get_project_root()
if not root_dir then return print("Error: Project root not found.") end
local guard_macro = header_name:upper():gsub("[^A-Z0-9]", "_") .. "_HPP"
local content = string.format([[
#ifndef %s
#define %s
#include <iostream>
// Function prototypes
void example_function();
#endif // %s
]], guard_macro, guard_macro, guard_macro)
utils.write_file(root_dir .. "/include/" .. header_name .. ".hpp", content)
end)
end
function M.get_project_root()
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/src") == 1 or vim.fn.filereadable(dir .. "/CMakeLists.txt") == 1 then
return dir
end
dir = vim.fn.fnamemodify(dir, ":h")
end
end
function M.build()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
local build_dir = root .. "/build"
local cmd = "cd " .. build_dir .. " && cmake --build ."
local term_buf = utils.open_float_terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.list_extend({ success and "Compilation successful!" or "Error during compilation:" }, vim.split(output, "\n", { trimempty = true })))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
function M.run()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
local build_dir = root .. "/build"
local files = vim.fn.glob(build_dir .. "/*.polydev", true, true)
if #files == 0 then return print("Error: No .polydev file found in build directory.") end
utils.open_float_terminal("cd " .. build_dir .. " && ./" .. files[1]:match("([^/]+)%.polydev$"))
end
return M
-13
View File
@@ -1,13 +0,0 @@
---@type table
local M = {}
---@type table|nil
M.opts = nil
---@param opts table
function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("html"), opts or {})
end
---@return table
return M
-50
View File
@@ -1,50 +0,0 @@
local utils = require("Polydev.utils")
local M = {}
M.keybinds = {}
M.opts = nil
function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("java"), opts or {})
for key, command in pairs(M.opts.keybinds) do
M.keybinds[command] = key
end
vim.api.nvim_create_user_command("JavaBuild", M.build, {})
vim.api.nvim_create_user_command("JavaRun", M.run, {})
if M.keybinds.JavaRun then
vim.keymap.set("n", M.keybinds.JavaRun, ":JavaRun<CR>", { silent = true })
end
if M.keybinds.JavaBuild then
vim.keymap.set("n", M.keybinds.JavaBuild, ":JavaBuild<CR>", { silent = true })
end
end
function M.build()
local project_root = vim.fn.expand("%:p:h"):match("(.*)/src")
if not project_root then return print("Error: Could not detect project root directory.") end
local out_dir = project_root .. "/build"
vim.fn.mkdir(out_dir, "p")
local compile_command = string.format("javac -d %s %s/*.java", out_dir, project_root .. "/src")
local compile_status = vim.fn.system(compile_command)
if vim.v.shell_error == 0 then
print("Compilation successful!")
else
print("Error during compilation. Opening terminal for details...")
local term_buf = utils.open_float_terminal(compile_command)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.split(compile_status, "\n", { trimempty = true }))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
end
function M.run()
local project_root = vim.fn.expand("%:p:h"):match("(.*)/src")
if not project_root then return print("Error: Must be inside the 'src' directory.") end
utils.open_float_terminal("java -cp " .. project_root .. "/build" .. " Main")
end
return M
-53
View File
@@ -1,53 +0,0 @@
---@module "Polydev.utils"
local utils = require("Polydev.utils")
---@type table
local M = {}
---@type table
M.keybinds = {}
---@type table|nil
M.opts = nil
---@param opts table
function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("lua"), opts or {})
for key, command in pairs(M.opts.keybinds) do
M.keybinds[command] = key
end
vim.api.nvim_create_user_command("LuaRun", M.run, {})
if M.keybinds.LuaRun then
vim.keymap.set("n", M.keybinds.LuaRun, ":LuaRun<CR>", { silent = true })
end
end
function M.run()
---@return string|nil
local function get_project_root()
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
local polydev_file = vim.fn.glob(dir .. "/*.polydev")
if polydev_file ~= "" then return dir end
dir = vim.fn.fnamemodify(dir, ":h")
end
return nil
end
---@return string
local function get_project_name()
return vim.fn.glob((M.get_project_root() or "") .. "/*.polydev"):match("([^/]+)%.polydev$")
end
if not get_project_root() or not get_project_name() then return print("Error: Project root not found.") end
local init_lua_path = get_project_root() .. "/lua/" .. get_project_name() .. "/init.lua"
if vim.fn.filereadable(init_lua_path) == 1 then
utils.open_float_terminal("lua " .. init_lua_path)
else
print("Error: " .. init_lua_path .. " not found in " .. get_project_root())
end
end
---@return table
return M
-81
View File
@@ -1,81 +0,0 @@
local utils = require("Polydev.utils")
local config = require("Polydev.configs")
local M = {}
M.keybinds = {}
M.opts = nil
function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, config.get("python"), opts or {})
for key, command in pairs(M.opts.keybinds) do
M.keybinds[command] = key
end
local root = M.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
vim.api.nvim_create_user_command("PythonPip", M.install_dependency, {})
vim.api.nvim_create_user_command("PythonRun", M.run, {})
if M.keybinds.PythonRun then
vim.keymap.set("n", M.keybinds.PythonRun, ":PythonRun<CR>", { silent = true })
end
if M.keybinds.PythonPip then
vim.keymap.set("n", M.keybinds.PythonPip, ":PythonPip<CR>", { silent = true })
end
end
function M.get_project_root()
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/venv") == 1 or vim.fn.filereadable(dir .. "/main.py") == 1 then
return dir
end
dir = vim.fn.fnamemodify(dir, ":h")
end
return nil
end
function M.install_dependency()
vim.ui.input({ prompt = "Enter pip module: " }, function(pip_module)
if not pip_module or pip_module == "" then
return print("Pip canceled")
end
utils.open_float_terminal("pip install " .. pip_module)
end)
end
function M.run()
local root = M.get_project_root()
if not root then
return print("Error: Project root not found.")
end
local main_file = root .. "/main.py"
if vim.fn.filereadable(main_file) == 0 then
return print("Error: main.py not found in project root.")
end
-- Detect current shell
local shell = vim.fn.getenv("SHELL") or ""
local venv_cmd
if shell:match("fish") then
local venv_fish = root .. "/venv/bin/activate.fish"
venv_cmd = vim.fn.filereadable(venv_fish) == 1 and "source " .. venv_fish .. " && " or ""
else
local venv_bash = root .. "/venv/bin/activate"
venv_cmd = vim.fn.filereadable(venv_bash) == 1 and "source " .. venv_bash .. " && " or ""
end
utils.open_float_terminal(venv_cmd .. "python3 " .. main_file)
end
return M
-52
View File
@@ -1,52 +0,0 @@
local utils = require("Polydev.utils")
local M = {}
M.keybinds = {}
M.opts = nil
function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("rust"), opts or {})
for key, command in pairs(M.opts.keybinds) do
M.keybinds[command] = key
end
vim.api.nvim_create_user_command("RustBuild", M.build, {})
vim.api.nvim_create_user_command("RustRun", M.run, {})
if M.keybinds.RustRun then
vim.keymap.set("n", M.keybinds.RustRun, ":RustRun<CR>", { silent = true })
end
if M.keybinds.RustBuild then
vim.keymap.set("n", M.keybinds.RustBuild, ":RustBuild<CR>", { silent = true })
end
end
function M.get_project_root()
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/src") == 1 then
return dir
end
dir = vim.fn.fnamemodify(dir, ":h")
end
end
function M.build()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
local cmd = "cargo build"
local term_buf = utils.open_float_terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.list_extend({ success and "Compilation successful!" or "Error during compilation:" }, vim.split(output, "\n", { trimempty = true })))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
function M.run()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
utils.open_float_terminal("cargo run")
end
return M
+35
View File
@@ -0,0 +1,35 @@
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
@@ -0,0 +1,23 @@
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
+81 -219
View File
@@ -1,53 +1,68 @@
---@module 'Polydev.utils'
local utils = require("Polydev.utils") local utils = require("Polydev.utils")
---
---@type table
local M = {} local M = {}
---@class TemplateLanguage local function extras(guard, file_type, file_name)
---@field run fun(project_name: string, project_root: string): nil 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
---@class Projects // Add code here
---@field java TemplateLanguage
---@field python TemplateLanguage #endif
---@field lua TemplateLanguage ]], guard_macro, guard_macro)
---@field c TemplateLanguage utils.write_file({ utils.get_project_root(), "include", file_name .. file_type }, content)
---@field cpp TemplateLanguage end
---@field rust TemplateLanguage
---@field html TemplateLanguage
---@alias TemplatesLanguageName "java" | "python" | "lua" | "c" | "cpp" | "rust" | "html"
---@type Projects
M.projects = { 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 = { java = {
run = function(project_name, project_root) run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name 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 for _, path in ipairs({ "/src", "/build" }) do vim.fn.mkdir(full_project_root .. path, "p") end
local main_java_content = [[ local content = [[
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Hello, World!"); System.out.println("Hello, World!");
} }
} }
]] ]]
utils.write_file(full_project_root .. "/src/Main.java", main_java_content) local gitignore = {
return nil "build/"
}
utils.init_git(full_project_root, gitignore)
utils.write_file({ full_project_root, "src", "Main.java" }, content)
end end
}, },
python = { python = {
run = function(project_name, project_root) run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.mkdir(full_project_root .. "/include", "p") vim.fn.mkdir(full_project_root .. "/include", "p")
utils.write_file(full_project_root .. "/main.py", [[ utils.write_file({ full_project_root, "main.py" }, [[
def main(): def main():
print("Hello, World!") print("Hello, World!")
if __name__ == "__main__": if __name__ == "__main__":
main() main()
]]) ]])
utils.write_file(full_project_root .. "/include/__init__.py", "") utils.write_file({ full_project_root, "include/__init__.py" }, "")
utils.write_file(full_project_root .. "/requirements.txt", "") utils.write_file({ full_project_root, "requirements.txt" }, "")
utils.write_file(full_project_root .. "/setup.py", string.format([[ utils.write_file({ full_project_root, "setup.py" }, string.format([[
from setuptools import setup, find_packages from setuptools import setup, find_packages
setup( setup(
@@ -58,6 +73,10 @@ setup(
python_requires=">=3.6", python_requires=">=3.6",
) )
]], project_name)) ]], project_name))
local gitignore = {
"venv/"
}
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/main.py") vim.cmd("edit " .. full_project_root .. "/main.py")
local venv_path = full_project_root .. "/venv" local venv_path = full_project_root .. "/venv"
vim.fn.system("python3 -m venv " .. venv_path) vim.fn.system("python3 -m venv " .. venv_path)
@@ -65,34 +84,13 @@ setup(
vim.fn.setenv("VIRTUAL_ENV", venv_path) vim.fn.setenv("VIRTUAL_ENV", venv_path)
vim.fn.setenv("PATH", venv_path .. "/bin:" .. vim.fn.getenv("PATH")) vim.fn.setenv("PATH", venv_path .. "/bin:" .. vim.fn.getenv("PATH"))
print("Virtual environment activated for " .. project_name) print("Virtual environment activated for " .. project_name)
return nil
end
},
lua = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/lua/" .. project_name }) do vim.fn.mkdir(full_project_root .. path, "p") end
utils.write_file(full_project_root .. "/lua/" .. project_name .. "/init.lua", [[
local M = {}
return M
]])
utils.write_file(full_project_root .. "/" .. project_name .. ".polydev", "[[DO NOT REMOVE THIS FILE]]")
vim.cmd("edit " .. full_project_root .. "/lua/" .. project_name .. "/init.lua")
return nil
end end
}, },
c = { c = {
run = function(project_name, project_root) run = function(project_name, project_root)
local full_project_root = vim.fn.expand(M.opts.project_root) .. "/" .. project_name 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 for _, path in ipairs({ "/src", "/build", "/include" }) do vim.fn.mkdir(full_project_root .. path, "p") end
utils.write_file(full_project_root .. "/build/" .. project_name .. ".polydev", project_name) utils.write_file({ full_project_root, "src/main.c" }, [[
utils.write_file(full_project_root .. "/src/main.c", [[
/* If you have vcpkg and want to use it:
vcpkg new --application
vcpkg add port <package_name>
*/
#include <stdio.h> #include <stdio.h>
int main() { int main() {
@@ -100,7 +98,7 @@ int main() {
return 0; return 0;
} }
]]) ]])
utils.write_file(full_project_root .. "/CMakeLists.txt", string.format([[ utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(%s) project(%s)
include_directories(include) include_directories(include)
@@ -113,39 +111,10 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
# find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg # find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg
# target_link_libraries(Game PRIVATE SDL3::SDL3) # target_link_libraries(Game PRIVATE SDL3::SDL3)
]], project_name, project_name)) ]], project_name, project_name))
utils.write_file(full_project_root .. "/CMakePresets.json", string.format([[ local gitignore = { "build/" }
# For the purposes of vcpkg, DO NOT REMOVE, but feel free to change as needed 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))
"version": 2,
"configurePresets": [
{
"name": "vcpkg",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
}
]
}
]]))
utils.write_file(full_project_root .. "/CMakeUserPresets.json", string.format([[
{
"version": 2,
"configurePresets": [
{
"name": "default",
"inherits": "vcpkg",
"environment": {
"VCPKG_ROOT": "/Users/<USER>/vcpkg"
}
}
]
}
]]))
vim.cmd("edit " .. full_project_root .. "/src/main.c") vim.cmd("edit " .. full_project_root .. "/src/main.c")
vim.fn.system(string.format("cd %s/build/ && cmake .. && cmake --build .", full_project_root))
end end
}, },
cpp = { cpp = {
@@ -154,13 +123,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
for _, path in ipairs({ "/src", "/build", "/include" }) do for _, path in ipairs({ "/src", "/build", "/include" }) do
vim.fn.mkdir(full_project_root .. path, "p") vim.fn.mkdir(full_project_root .. path, "p")
end end
utils.write_file(full_project_root .. "/build/" .. project_name .. ".polydev", project_name) utils.write_file({ full_project_root, "src/main.cpp" }, [[
utils.write_file(full_project_root .. "/src/main.cpp", [[
/* If you have vcpkg and want to use it:
vcpkg new --application
vcpkg add port <package_name>
*/
#include <iostream> #include <iostream>
int main() { int main() {
@@ -168,7 +131,7 @@ int main() {
return 0; return 0;
} }
]]) ]])
utils.write_file(full_project_root .. "/CMakeLists.txt", string.format([[ utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(%s) project(%s)
include_directories(include) include_directories(include)
@@ -181,40 +144,11 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
# find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg # find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg
# target_link_libraries(Game PRIVATE SDL3::SDL3) # target_link_libraries(Game PRIVATE SDL3::SDL3)
]], project_name, project_name)) ]], project_name, project_name))
utils.write_file(full_project_root .. "/CMakePresets.json", string.format([[
# For the purposes of vcpkg, DO NOT REMOVE, but feel free to change as needed
{
"version": 2,
"configurePresets": [
{
"name": "vcpkg",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
}
]
}
]]))
utils.write_file(full_project_root .. "/CMakeUserPresets.json", string.format([[
{
"version": 2,
"configurePresets": [
{
"name": "default",
"inherits": "vcpkg",
"environment": {
"VCPKG_ROOT": "/Users/<USER>/vcpkg"
}
}
]
}
]])) local gitignore = { "build/" }
vim.fn.system(string.format("cd %s/build/ && cmake .. && cmake --build .", full_project_root)) 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") vim.cmd("edit " .. full_project_root .. "/src/main.cpp")
return nil
end end
}, },
rust = { rust = {
@@ -227,6 +161,9 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
html = { html = {
run = function(project_name, project_root) run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name 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 = [[ local main_html_content = [[
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@@ -241,118 +178,50 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
</body> </body>
</html> </html>
]] ]]
utils.write_file(full_project_root .. "index.html", main_html_content) utils.write_file({ full_project_root, "index.html" }, main_html_content)
end end
}, },
} }
---@class TemplateFile
---@field run fun(file_name: string): nil
---@class Files
---@field java TemplateFile
---@field python TemplateFile
---@field lua TemplateFile
---@field c TemplateFile
---@field cpp TemplateFile
---@field rust TemplateFile
---@field html TemplateFile
---@alias TemplatesFileName "java" | "python" | "lua" | "c" | "cpp" | "rust" | "html"
---@type Files
M.files = { M.files = {
lua = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "lua", utils.get_project_name(), file_name .. ".lua"}, "")
end
},
java = { java = {
run = function (file_name) run = function (file_name)
local root_dir = vim.fn.expand("%:p:h"):match("(.*)/src") utils.write_file({ utils.get_project_root(), "src", file_name .. ".java" }, string.format([[
if not root_dir then return print("Error: src directory not found.") end
local java_content = string.format([[
public class %s { public class %s {
// New File // New File
} }
]], class_name) ]], file_name))
utils.write_file(root_dir .. "/src/" .. file_name .. ".java", java_content)
end end
}, },
python = { python = {
run = function (file_name) run = function (file_name)
if not file_name:match("%.py$") then file_name = file_name .. ".py" end utils.write_file({ utils.get_project_root(), "include", file_name .. ".py" }, "")
local root_dir = M.get_project_root()
if not root_dir then return print("Error: Project root not found.") end
local file_path = root_dir .. "/include/" .. file_name
utils.write_file(file_path, "")
end
},
lua = {
run = function (file_name)
local function get_project_root()
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
local polydev_file = vim.fn.glob(dir .. "/*.polydev")
if polydev_file ~= "" then return dir end
dir = vim.fn.fnamemodify(dir, ":h")
end
return nil
end
local function get_project_name() return vim.fn.glob((get_project_root() or "") .. "/*.polydev"):match("([^/]+)%.polydev$") end
if not get_project_root() or not get_project_name() then return print("Error: Project root not found.") end
utils.write_file(get_project_root() .. "/lua/" .. get_project_name() .. "/" .. file_name .. ".lua", "")
end end
}, },
c = { c = {
run = function (file_name) run = function (file_name)
local function get_project_root() utils.write_file({ utils.get_project_root(), "src", file_name .. ".c" }, "")
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/src") == 1 or vim.fn.filereadable(dir .. "/CMakeLists.txt") == 1 then
return dir
end
dir = vim.fn.fnamemodify(dir, ":h")
end
end
if not file_name or file_name == "" then return print("File creation canceled.") end
local root_dir = get_project_root()
if not root_dir then return print("Error: Project root not found.") end
utils.write_file(root_dir .. "/src/" .. file_name .. ".c", "")
end end
}, },
cpp = { cpp = {
run = function (file_name) run = function (file_name)
local function get_project_root() utils.write_file({ utils.get_project_root(), "src", file_name .. ".cpp" }, "")
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/src") == 1 or vim.fn.filereadable(dir .. "/CMakeLists.txt") == 1 then
return dir
end
dir = vim.fn.fnamemodify(dir, ":h")
end
end
local root_dir = get_project_root()
if not root_dir then return print("Error: Project root not found.") end
utils.write_file(root_dir .. "/src/" .. file_name .. ".cpp", "")
end end
}, },
rust = { rust = {
run = function (file_name) run = function (file_name)
local function get_project_root() utils.write_file({ utils.get_project_root(), "src", file_name .. ".rs" }, "")
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/src") == 1 then
return dir
end
dir = vim.fn.fnamemodify(dir, ":h")
end
end
local root_dir = get_project_root()
if not root_dir then return print("Error: Project root not found.") end
utils.write_file(root_dir .. "/src/" .. file_name .. ".rs", "")
end end
}, },
html = { html = {
run = function (file_name) run = function (file_name)
local html_content = string.format([[ utils.write_file({ ".", file_name .. ".html" }, string.format([[
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
@@ -365,29 +234,22 @@ public class %s {
</body> </body>
</html> </html>
]]) ]]))
utils.write_file("./" .. file_name .. ".html", html_content)
end end
} }
} }
---@param lang TemplatesLanguageName M.extras = {
---@param project_root string run = function (lang, file_name)
function M.create_project(lang, project_root) if lang == "c" then
vim.ui.input({ prompt = "Enter project name: " }, function(project_name) extras("_H", ".h", file_name)
if not project_name or project_name == "" then return print("Project creation canceled.") end print("Successful creation of " .. file_name .. ".h")
M.projects[lang].run(project_name, project_root) end
end) if lang == "cpp" then
end extras("_HPP", ".hpp", file_name)
print("Successful creation of " .. file_name .. ".hpp")
end
end
}
---@param lang TemplatesFileName
function M.create_new_file(lang)
vim.ui.input({ prompt = "Enter file name: " }, function(file_name)
if not file_name or file_name == "" then return print("File creation canceled.") end
M.files[lang].run(file_name)
end)
end
---@return any
return M return M
+404
View File
@@ -0,0 +1,404 @@
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
+65 -22
View File
@@ -1,26 +1,76 @@
local M = {} local M = {}
M.opts = {} M.opts = {}
function M.setup(opts) function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("terminal"), opts or {}) M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("terminal"), opts or {})
end end
function M.write_file(path, content) ---@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) local file = assert(io.open(path, "w"), "Error creating file: " .. path)
file:write(content) file:write(content)
file:close() file:close()
vim.cmd("edit " .. path) vim.cmd("edit " .. path)
print(path .. " created successfully!")
end end
function M.open_float_terminal(cmd) ---@param path string
local ui = vim.api.nvim_list_uis()[1] ---@param gitignore_lines table
function M.init_git(path, gitignore_lines)
vim.fn.mkdir(path, "p")
vim.fn.system({ "git", "-C", path, "init" })
local width = math.max(1, math.floor(ui.width * 0.9) - M.opts.left_padding or 0 - M.opts.right_padding or 0) if gitignore_lines and #gitignore_lines > 0 then
local height = math.max(1, math.floor(ui.height * 0.9) - M.opts.top_padding or 0 - M.opts.bottom_padding or 0) local gitignore_path = { path, ".gitignore" }
local row = math.max(1, math.floor((ui.height - height) / 2) + (M.opts.top_padding or 0)) local contents = table.concat(gitignore_lines, "\n")
local col = math.max(1, math.floor((ui.width - width) / 2) + (M.opts.left_padding or 0)) 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 buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_open_win(buf, true, { local win = vim.api.nvim_open_win(buf, true, {
@@ -30,21 +80,14 @@ function M.open_float_terminal(cmd)
row = row, row = row,
col = col, col = col,
style = "minimal", style = "minimal",
border = M.opts.border and "rounded" or "none", 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.api.nvim_win_set_option(win, "winblend", vim.o.pumblend) vim.fn.termopen(table.concat(cmd, "/"))
vim.api.nvim_win_set_option(win, "winhighlight", "Normal:Pmenu,FloatBorder:Pmenu")
vim.api.nvim_win_set_option(win, "cursorline", true)
vim.api.nvim_win_set_option(win, "scrolloff", 5)
if(M.opts.number == true) then
vim.api.nvim_win_set_option(win, "number", true)
if(M.opts.relativenumber == true) then
vim.api.nvim_win_set_option(win, "relativenumber", true)
end
end
vim.fn.termopen(cmd)
vim.api.nvim_buf_set_keymap(buf, "n", "<ESC>", "i<C-\\><C-n>:q<CR>", { noremap = true, silent = true }) vim.api.nvim_buf_set_keymap(buf, "n", "<ESC>", "i<C-\\><C-n>:q<CR>", { noremap = true, silent = true })
return buf, win return buf, win
end end
+2
View File
@@ -9,6 +9,8 @@ nav:
- Cpp: languages/cpp.md - Cpp: languages/cpp.md
- Lua: languages/lua.md - Lua: languages/lua.md
- Python: languages/python.md - Python: languages/python.md
- Rust: languages/rust.md
- Html: languages/html.md
theme: theme:
name: material name: material
features: features: