58 Commits
Author SHA1 Message Date
Andrew Haynes 2b30e36fad major changes to try and fix a bunch of random bugs 2026-08-03 16:03:08 -04:00
Andrew Haynes 8d41141e9a configs should update properly 2026-03-31 18:38:18 -04:00
Andrew Haynes 919d141c6a LANG: Javascript finally fixed...hopefully 2026-03-30 00:17:21 -04:00
Andrew Haynes 89bf0333c4 ? 2026-03-30 00:16:04 -04:00
Andrew Haynes 9210dff133 ? 2026-03-30 00:12:17 -04:00
Andrew Haynes 262e377873 ? 2026-03-30 00:09:40 -04:00
Andrew Haynes 5cec285828 ? 2026-03-30 00:08:30 -04:00
Andrew Haynes 22215cccda ? 2026-03-30 00:04:53 -04:00
Andrew Haynes 2ca6c62cd8 LANG: javascript - lets see if this works 2026-03-29 00:47:50 -04:00
Andrew Haynes d99dc30dcd LANG: added javascript init 2026-03-29 00:27:54 -04:00
Andrew Haynes 62015919dd plz 2026-03-19 14:01:42 -04:00
Andrew Haynes e0cbc48cc0 c/c++ changes 2026-03-07 13:45:34 -05:00
Gentoo 15718d57fa .clang-format for c/c++ 2026-03-06 03:55:26 -05:00
DarthMooMancer c907211784 Update README.md 2025-12-10 17:58:20 +00:00
DarthMooMancer 053c567618 cleaning 2025-12-01 01:08:04 -05:00
DarthMooMancer faf87f3643 Update README.md 2025-12-01 06:07:13 +00:00
DarthMooMancer 1df75ee212 removing github 2025-12-01 00:40:00 -05:00
DarthMooMancer ce406bfad3 c++ 2025-11-13 02:24:38 -05:00
DarthMooMancer 0dec930412 c++ 2025-11-13 02:23:38 -05:00
DarthMooMancer d7b949d9f9 ui changes 2025-10-30 23:03:07 -04:00
DarthMooMancer bf56094156 fixes 2025-10-30 22:33:34 -04:00
DarthMooMancer 1a450ff79a wip 2025-10-26 21:04:05 -04:00
DarthMooMancer 76791fd7c1 wip 2025-10-26 21:02:59 -04:00
DarthMooMancer 45fcdf78be wip 2025-10-26 21:01:40 -04:00
DarthMooMancer d1cb867cf8 c++ fix 2025-10-03 09:23:57 -04:00
Andrew Haynes 5bf74a6639 Update templates.lua 2025-09-19 13:47:27 -04:00
dmm 2b440c2935 Update issue templates 2025-09-07 15:12:33 +00:00
dmm 5420c54d9a Create CONTRIBUTING.md 2025-09-07 15:08:25 +00:00
dmm ad97a31a31 Create CODE_OF_CONDUCT.md 2025-09-07 15:06:21 +00:00
DarthMooMancer 0a8495fe79 fix 2025-09-04 21:13:24 -04:00
DarthMooMancer a246f2ab03 Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-09-04 21:07:31 -04:00
DarthMooMancer 5765c8ea19 fix: c/c++ had compile commands linked unnecassarily 2025-09-04 21:07:27 -04:00
dmm e701aa1feb Update README.md 2025-09-04 20:52:09 -04:00
DarthMooMancer bc825895ac fix: changed formatting and defaults for c/c++ 2025-09-01 00:36:35 -04:00
DarthMooMancer 0cc4374865 wip 2025-08-22 19:30:24 -04:00
DarthMooMancer 66ae61f2c9 fix(ui): closes ui when making projects and files 2025-07-20 02:27:24 -04:00
DarthMooMancer cf84fe2080 feat(plugin.Polydev): Added for automatically starting the plugin so opts or require are not necessary 2025-06-29 16:09:45 -04:00
DarthMooMancer beddb26757 chore(presets): formatting presets to be nicer 2025-06-21 03:50:26 -04:00
DarthMooMancer df473b1d33 fix(ui): forgot to add keybinds to new ui 2025-06-21 03:35:11 -04:00
DarthMooMancer e3fdeb53b3 fix(README): readme no longer has warning about ui as I have it fixed 2025-06-21 02:56:42 -04:00
DarthMooMancer 8c2498d00f feat(ui): removed nui dependency and now have tabbed ui for current project and recent folders and files
chore(all): just cleaned up and removed some redundant code
2025-06-21 02:56:01 -04:00
DarthMooMancer 69c648c4f4 Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-05-27 13:50:55 -04:00
DarthMooMancer 60e5d9ea2f refactor(ui): removed the preview and search popups. Refactored project specific code be faster and more maintained 2025-05-27 13:50:50 -04:00
DarthMooMancer 109489a2aa Update README.md 2025-05-27 13:49:21 -04:00
DarthMooMancer 6937318b2e Update README.md 2025-05-27 13:46:26 -04:00
DarthMooMancer 23bc6c2bfc Merge branch 'main' of https://github.com/DarthMooMancer/Polydev 2025-05-22 08:12:32 -04:00
DarthMooMancer 38284658dd chore: removing redundant code 2025-05-22 08:12:27 -04:00
DarthMooMancer 759278b9ff Update README.md 2025-05-20 14:37:42 -04:00
DarthMooMancer 14b302151b fix(utils): fixed bottom split and added sizing for splits 2025-05-20 09:27:04 -04:00
DarthMooMancer e6c3353b51 feat(utils): added ability to have floating or split windows and anchors of where each are
fix(ui): also changed deprecated features to use newer features by
neovim
2025-05-17 18:33:55 -04:00
DarthMooMancer eea8def35c docs(appearance): update 2025-05-16 13:10:57 -04:00
DarthMooMancer d5fadfa55e docs(appearance): added appearance tab 2025-05-16 12:59:53 -04:00
DarthMooMancer 7e047478d5 fix(deprecated): replacing deprecated code throughout project
rework: moved load_language_module to languages as it makes more sense
2025-05-16 10:53:34 -04:00
DarthMooMancer 9eb38ba06e docs(mkdocs.yml): removed language specific docs 2025-05-16 09:40:25 -04:00
DarthMooMancer 85f05563ce docs(languages): added gitignore to each language fixing https://github.com/DarthMooMancer/Polydev/issues/6 2025-05-16 09:37:54 -04:00
DarthMooMancer 7646aa3295 fix(docs): forgot to push mkdocs.yml 2025-05-16 01:04:46 -04:00
DarthMooMancer 3942f88ef6 docs(languages): removed individual language files and moved them all to one 2025-05-16 01:01:11 -04:00
DarthMooMancer 46eb126ebe fix(.gitignore): removed everything but venv as they are no longer in project 2025-05-16 00:40:39 -04:00
26 changed files with 1134 additions and 1371 deletions
-22
View File
@@ -1,22 +0,0 @@
name: ci
on:
push:
branches:
- master
- main
permissions:
contents: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.x
- uses: actions/cache@v3
with:
key: ${{ github.ref }}
path: .cache
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force
-1
View File
@@ -1,3 +1,2 @@
LICENSE LICENSE
Lua_Annotation_CheatSheet/
venv/ venv/
+128
View File
@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
dmm.dev@pm.me.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+1
View File
@@ -0,0 +1 @@
- Its really simple. Just if you see an error/bug, enhancment or feature to be improved on just make an issue or make a pr.
+4 -9
View File
@@ -1,18 +1,14 @@
<h1 align="center">Polydev</h1> <h1 align="center">Polydev</h1>
<p align="center"><em>A multi-language project managing plugin for file creation, building, and running code—all within neovim. Whether you're coding in Java, Python, Lua, Rust, or more, Polydev provides seamless integration to boost your productivity inside Neovim.</em></p> <p align="center"><em>A multi-language project managing plugin for file creation, building, and running code—all within neovim. Whether you're coding in C/C++ Java, Python, Lua, Rust, and more, Polydev provides seamless integration to boost your productivity inside Neovim.</em></p>
<p align="center"> <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/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/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/License-Apache-yellow.svg?style=for-the-badge" />
<img src="https://img.shields.io/badge/Docs-Available-blue?style=for-the-badge&logo=readthedocs&logoColor=white" /> <img src="https://img.shields.io/badge/Docs-Available-blue?style=for-the-badge&logo=readthedocs&logoColor=white" />
</p> </p>
<p align="center">
<img src="https://github.com/user-attachments/assets/c8e84056-5080-4ec3-ba15-30be61faaf68" alt="Polydev Preview" width="720"/>
</p>
## Features ## Features
@@ -23,9 +19,9 @@
* Integrated terminal for flexible command execution * Integrated terminal for flexible command execution
* Lightweight, fast project manager UI * Lightweight, fast project manager UI
* Minimal configuration with extensibility in mind * Minimal configuration with extensibility in mind
* Built-in diagnostics with `:checkhealth Polydev`
> 📚 [View the full documentation](https://darthmoomancer.github.io/Polydev/) for setup, configuration, and usage details. > 📚 [View the full documentation](https://git.moomancer.xyz/DarthMooMancer/polydev/wiki/Home$0) for setup, configuration, and usage details.
## Supported Languages ## Supported Languages
@@ -45,8 +41,7 @@ Additional language support is planned for future releases.
Current focus: Current focus:
* **Refactoring and internal cleanup.** * **Refactoring and internal cleanup.**
* **Remaking it not in nui to make tabs, mainly for recent projects as the main page**
Feature additions will resume after this phase.
## Contributing ## Contributing
-70
View File
@@ -1,70 +0,0 @@
<p align="center"><em>A multi-language project managing plugin for file creation, building, and running code—all within neovim. Whether you're coding in Java, Python, Lua, Rust, or more, Polydev provides seamless integration to boost your productivity inside Neovim.</em></p>
<p align="center">
<img src="https://img.shields.io/badge/Lua-1e90ff?style=for-the-badge&logo=lua&logoColor=white" />
<img src="https://img.shields.io/badge/Neovim-0.10%2B-32c48d?style=for-the-badge&logo=neovim&logoColor=white" />
<img src="https://img.shields.io/github/stars/DarthMooMancer/Polydev?style=for-the-badge&logo=github" />
<img src="https://img.shields.io/badge/License-Apache-yellow.svg?style=for-the-badge" />
</p>
<p align="center">
<img src="https://github.com/user-attachments/assets/c8e84056-5080-4ec3-ba15-30be61faaf68" alt="Polydev Preview" width="720"/>
</p>
## **Why Polydev**?
Working across multiple languages often means repetitive setup and constant context switching. Polydev eliminates this friction by offering:
* Project templates per language
* Custom keybindings for essential actions
* Floating terminal integration
* Automated file and folder generation
* A plugin-first design for easy extensibility
## **Core Features**
* **Language Profiles**
Define settings per language including `project_root`, keymaps, and build commands.
* **Floating Terminals**
Run build, and run commands in a clean, isolated terminal window inside Neovim.
* **Scaffolding**
Quickly generate boilerplate and structured directories for new projects.
* **Custom Keybinds**
Map actions like `Run`, `PipInstall`, `Open Manager`, `etc` to your preferred keys.
* **Pluggable Design**
Easily extend functionality with custom language presets and commands.
## **Who It's For**
* Developers who work in multiple languages
* Neovim plugin authors or power users
* Anyone who wants a faster, more unified project workflow
## **Design Goals**
* **Consistency**
Offer a predictable workflow across languages and tools.
* **Extensibility**
Support custom configurations, commands, and language integrations.
* **Simplicity**
Reduce boilerplate, context switching, and friction.
## **Real-World Example**
If you switch often between Rust, Lua, and Python:
1. Polydev sets up your project layout automatically.
2. Creates boilerplate like `main.rs`, `init.lua`, or `main.py`.
3. Maps commands to keys (e.g. `<leader>pr` to run, `<leader>po` to open the manager).
4. Opens a floating terminal with build or run output — no extra configuration required.
-43
View File
@@ -1,43 +0,0 @@
## **Lazy.nvim**
```lua
return {
"DarthMooMancer/Polydev",
dependencies = {
"MunifTanjim/nui.nvim"
},
opts = {}, -- Setup is later on
}
```
---
## **Mini.deps**
```lua
MiniDeps.add({
source = "DarthMooMancer/Polydev"
depends = {
"MunifTanjim/nui.nvim"
}
})
require("Polydev").setup({})
```
---
## **Packer.nvim**
```lua
use({
"DarthMooMancer/Polydev",
requires = {
"MunifTanjim/nui.nvim"
},
})
require("Polydev").setup({})
```
---
-30
View File
@@ -1,30 +0,0 @@
#### File Structure 📂
This is the recommended file structure for your C projects using Polydev:
| Directory/File Path | Description |
|----------------------------|------------------------------------------------------|
| `CMakeLists.txt` | Configuration file for your project build |
| `src/` | Folder containing source files for the project |
| `main.c` | Main C file for the project |
| `*.c` | Additional C source files |
| `build/` | Folder where the build artifacts will be generated |
| `include/` | Folder for header files |
| `*.h` | C header files |
#### Example Structure:
```md
Projects/
└── C/
└── Project_Name/
├── CMakeLists.txt
├── src/
│ ├── main.c
│ └── *.c
├── build/
│ └── <CMAKE_FILES>
│ └── <main-executable>
└── include/
└── *.h
```
---
-31
View File
@@ -1,31 +0,0 @@
#### File Structure 📂
This is the recommended file structure for your C projects using Polydev:
| Directory/File Path | Description |
|----------------------------|------------------------------------------------------|
| `CMakeLists.txt` | Configuration file for your project build |
| `src/` | Folder containing source files for the project |
| `main.cpp` | Main Cpp file for the project |
| `*.cpp` | Additional Cpp source files |
| `build/` | Folder where the build artifacts will be generated |
| `include/` | Folder for header files |
| `*.hpp` | Cpp header files |
#### Example Structure:
```md
Projects/
└── Cpp/
└── Project_Name/
├── CMakeLists.txt
├── src/
│ ├── main.cpp
│ └── *.cpp
├── build/
│ └── <CMAKE_FILES>
│ └── <main-executable>
└── include/
└── *.hpp
```
---
-1
View File
@@ -1 +0,0 @@
Nothing here yet! Html is supported however!
-32
View File
@@ -1,32 +0,0 @@
### **Java Features**
* **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.
* **Project File Management**:
The plugin manages your Java project files efficiently, helping you quickly add new Java files to the `src` directory. It also ensures that your build and run processes are streamlined.
---
#### File Structure
Here’s the recommended structure for your Java projects using Polydev:
| Directory/File Path | Description |
|----------------------------|------------------------------------------------------|
| `src/` | Contains the source code files, including `Main.java` |
| `build/` | Contains compiled `.class` files |
| `Main.java` | The main entry point of your Java project |
#### Example Structure:
```md
Projects/
└── Java/
└── Project_Name/
├── src/
│ └── Main.java
└── build/
└── *.class
```
---
-31
View File
@@ -1,31 +0,0 @@
### **Lua Features**
* **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.
* **Create New Lua Files**:
With the `<leader>nf` keybind, you can quickly create new Lua files in the `src` directory, maintaining an organized project structure.
---
#### File Structure 📂
Here’s the suggested directory structure for your Lua projects with Polydev:
| Directory/File Path | Description |
|----------------------------|-----------------------------------------------------|
| `lua/` | Directory containing the main Lua project files |
| `lua/<Project_name>/init.lua` | The main entry point for your Lua project |
##### Example File Structure:
```md
Projects/
└── Lua/
└── Project_Name/
└── lua/
└── Project_name/
└── init.lua -- Main Lua file
```
---
-40
View File
@@ -1,40 +0,0 @@
### **Python Features**
Here are some cool features available for Python projects using Polydev:
- **Automatic Virtual Environment Creation** 🔧
Each Python project automatically sets up and uses a new virtual environment. You don’t need to worry about environment management. Just install your dependencies with `pip` as needed.
- **Dependency Management with Pip** 📦
Need to install Python modules? Simply type the name of the module in the terminal, and Polydev will take care of the installation using `pip`. You can even update `pip` if required, ensuring smooth installation.
- **Effortless Dependency Handling** ⚡
You no longer need to manually activate or deactivate virtual environments. With Polydev, the environment is set up and activated automatically, simplifying your workflow.
---
#### **File Structure**
Here’s the recommended structure for your Python projects using Polydev:
| Directory/File Path | Description |
|----------------------------|------------------------------------------------------|
| `requirements.txt` | File for listing project dependencies |
| `setup.py` | Python project setup file |
| `tests/` | Folder containing test files |
| `venv/` | Virtual environment folder |
| `main.py` | Main Python file for your project |
#### **Tree Structure**:
```md
Projects/
└── Python/
└── Project_Name/
├── main.py
├── requirements.txt
├── setup.py
├── tests/
└── venv/
```
---
-1
View File
@@ -1 +0,0 @@
Nothing here yet! Rust is supported however!
-127
View File
@@ -1,127 +0,0 @@
## **Project Manager**
> Note: The project manager closely follows the netrw keybinds and allows for project management all in one spot
| Binding | Description |
|------------------|-----------------|
| **ENTER** | `Open file / Enter directory` |
| **DELETE** | `Go to parent directory` |
| **/** | `Filter (fuzzy search)` |
| **a** | `Create new folder` |
| **%** | `Create new file` |
| **x** | `Create new auxilary file (ex. headers)` |
| **d** | `Create new project` |
| **R** | `Rename file/folder` |
| **D** | `Delete file/folder` |
| **ESC** | `Quit popup` |
> **WARNING**: Do not copy the defaults. Only change what you need for your workflow!
## **Project Root**
```lua
-- Automatically creates a project root if not already made.
-- Stores all projects in this root
-- Global --
globals = {
project_root = "~/Projects"
}
-- Lua --
lua = {
project_root = "~/{global_root}/Lua"
}
-- Html --
html = {
project_root = "~/{global_root}/Html"
}
-- Rust --
rust = {
project_root = "~/{global_root}/Rust"
}
-- Java --
java = {
project_root = "~/{global_root}/Java"
}
-- Python --
python = {
project_root = "~/{global_root}/Python"
}
-- C --
c = {
project_root = "~/{global_root}/C"
}
-- C++ --
cpp = {
project_root = "~/{global_root}/CPP"
}
```
## **Keybinds**
```lua
-- globals --
globals = {
keybinds = {
["<leader>po"] = "PolydevManager",
}
}
-- rust --
rust = {
keybinds = {
["<leader>pr"] = "RustRun",
}
}
-- java --
java = {
keybinds = {
["<leader>pr"] = "JavaRun",
}
}
-- python --
python = {
keybinds = {
["<leader>pr"] = "PythonRun",
["<leader>pb"] = "PythonPip",
}
}
-- lua --
lua = {
keybinds = {
["<leader>pr"] = "LuaRun",
}
}
-- c --
c = {
keybinds = {
["<leader>pr"] = "CRun",
}
}
-- cpp --
cpp = {
keybinds = {
["<leader>pr"] = "CppRun",
}
}
```
## **Terminal Configuration**
```lua
-- In Neovim 0.11+, numbers don't work so they will be reimplemented later
terminal = {
preset = nil, -- also try : ("right", "corner")
border = true
}
```
+68 -65
View File
@@ -1,80 +1,83 @@
local M = {} local M = {}
M.defaults = {
globals = {
project_root = "~/Projects",
keybinds = {
["<leader>po"] = "PolydevManager",
},
},
terminal = {
preset = nil,
border = {
enabled = true,
type = "rounded",
},
},
}
local function default_languages(project_root)
return {
rust = {
project_root = project_root .. "/Rust",
keybinds = {
["<leader>pr"] = "RustRun",
},
},
java = {
project_root = project_root .. "/Java",
keybinds = {
["<leader>pr"] = "JavaRun",
},
},
lua = {
project_root = project_root .. "/Lua",
keybinds = {
["<leader>pr"] = "LuaRun",
},
},
c = {
project_root = project_root .. "/C",
keybinds = {
["<leader>pr"] = "CRun",
},
},
cpp = {
project_root = project_root .. "/CPP",
keybinds = {
["<leader>pr"] = "CppRun",
},
},
html = {
project_root = project_root .. "/Html",
},
}
end
M.user_config = {} 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 user_opts = user_opts or {}
M.user_config = vim.tbl_deep_extend("force", {}, M.defaults, user_opts or {}) local project_root = (user_opts.globals and user_opts.globals.project_root) or "~/personal/Projects"
local defaults = {
rust = {
project_root = project_root .. "/Rust",
keybinds = {
["<leader>pr"] = "RustRun",
},
},
javascript = {
project_root = project_root .. "/Javascript",
keybinds = {
["<leader>pr"] = "JavascriptRun",
},
},
java = {
project_root = project_root .. "/Java",
keybinds = {
["<leader>pr"] = "JavaRun",
},
},
lua = {
project_root = project_root .. "/Lua",
keybinds = {
["<leader>pr"] = "LuaRun",
},
},
c = {
project_root = project_root .. "/C",
keybinds = {
["<leader>pr"] = "CRun",
},
},
cpp = {
project_root = project_root .. "/CPP",
keybinds = {
["<leader>pr"] = "CppRun",
},
},
python = {
project_root = project_root .. "/Python",
keybinds = {
["<leader>pr"] = "PythonRun",
["<leader>pb"] = "PythonPip",
},
},
html = {
project_root = project_root .. "/Html",
},
globals = {
project_root = project_root,
keybinds = {
["<leader>po"] = "PolydevOpen",
},
},
terminal = {
mode = "split",
win = {
type = "horizontal", anchor = "bottom", size = "20"
},
border = {
enabled = true,
type = "rounded",
},
},
}
-- Now use the final resolved project_root from user_config M.user_config = vim.tbl_deep_extend("force", defaults, user_opts)
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 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 M return M
+157
View File
@@ -0,0 +1,157 @@
local ok, health = pcall(require, "vim.health")
if not ok then
health = nil
end
local new_api = health ~= nil and type(health.start) == "function"
local function report_start(name)
if new_api then health.start(name) else vim.health.report_start(name) end
end
local function report_ok(msg)
if new_api then health.ok(msg) else vim.health.report_ok(msg) end
end
local function report_info(msg)
if new_api then health.info(msg) else vim.health.report_info(msg) end
end
local function report_warn(msg, advice)
if new_api then
health.warn(msg, advice)
else
vim.health.report_warn(msg, advice)
end
end
local function report_error(msg, advice)
if new_api then
health.error(msg, advice)
else
vim.health.report_error(msg, advice)
end
end
local M = {}
local function fmt_langs(langs)
if type(langs) == "table" then
return "[" .. table.concat(langs, ", ") .. "]"
end
return "[" .. tostring(langs) .. "]"
end
local function check_nvim_version()
if vim.fn.has("nvim-0.10") == 1 then
report_ok(string.format("Neovim %s detected.", tostring(vim.version())))
else
report_error("Polydev requires Neovim 0.10 or newer.", "You are running " .. tostring(vim.version()))
end
end
local function check_setup()
local ok_configs, configs = pcall(require, "Polydev.configs")
if not ok_configs then
report_error("Could not load Polydev.configs", tostring(configs))
return nil
end
if next(configs.user_config or {}) == nil then
report_warn("Polydev.setup() has not run.",
"Add require('Polydev').setup() to your Neovim config, or make sure plugin/Polydev.lua is sourced by your plugin manager.")
return nil
end
report_ok("Polydev.setup() ran and the config is loaded.")
return configs
end
local function check_project_root(configs)
if not configs then return end
local root = configs.get("globals").project_root
local expanded = vim.fn.expand(root)
if vim.fn.isdirectory(expanded) == 1 then
if vim.fn.filewritable(expanded) == 2 then
report_ok(string.format("project_root exists and is writable: %s", expanded))
else
report_warn(string.format("project_root exists but is not writable: %s", expanded))
end
else
report_warn(string.format("project_root does not exist yet: %s", expanded),
"It is created automatically the first time the manager is opened.")
end
end
local function check_ui_input()
local ok_default, default = pcall(require, "vim.ui")
if ok_default and default.input and vim.ui.input ~= default.input then
report_warn("vim.ui.input has been overridden, likely by a UI plugin such as dressing.nvim or nui.nvim.",
"An asynchronous override can break project/file creation from the manager. Polydev now uses callbacks, but report here if it still misbehaves.")
else
report_ok("vim.ui.input is Neovim's default (synchronous) implementation.")
end
end
local function check_tools()
local tools = {
{ name = "git", langs = "all" },
{ name = "node", langs = "javascript" },
{ name = "python3", langs = "python" },
{ name = "pip3", langs = "python" },
{ name = "javac", langs = "java" },
{ name = "java", langs = "java" },
{ name = "cmake", langs = { "c", "cpp" } },
{ name = "cc", langs = { "c", "cpp" } },
{ name = "clang", langs = { "c", "cpp" } },
{ name = "clang-format", langs = { "c", "cpp" } },
{ name = "clang-tidy", langs = { "c", "cpp" } },
{ name = "cargo", langs = "rust" },
{ name = "lua", langs = "lua" },
{ name = "luajit", langs = "lua" },
}
for _, t in ipairs(tools) do
if vim.fn.executable(t.name) == 1 then
report_ok(string.format("%s is available for %s.", t.name, fmt_langs(t.langs)))
else
report_warn(string.format("%s was not found.", t.name),
"Project templates for " .. fmt_langs(t.langs) .. " may fail without it.")
end
end
if vim.fn.executable("python3") == 1 then
vim.fn.system("python3 -c 'import venv' 2>/dev/null")
if vim.v.shell_error == 0 then
report_ok("python3 venv module is available.")
else
report_warn("python3 venv module is missing.",
"Python project creation sets up a virtualenv and needs python3 -m venv.")
end
end
end
local function check_walkup()
local scripts = vim.api.nvim_get_runtime_file("bash_scripts/walkup.sh", false)
if #scripts == 0 then
report_error("bash_scripts/walkup.sh was not found on the runtimepath.",
"Reinstall the plugin so bash_scripts/ sits next to lua/ and plugin/.")
return
end
local script = scripts[1]
if vim.fn.executable(script) == 1 then
report_ok(string.format("bash_scripts/walkup.sh found and executable: %s", script))
else
report_warn(string.format("bash_scripts/walkup.sh is not executable: %s", script),
"Run: chmod +x " .. script)
end
end
function M.check()
report_start("Polydev")
check_nvim_version()
local configs = check_setup()
check_project_root(configs)
check_ui_input()
check_tools()
check_walkup()
end
return M
+42 -20
View File
@@ -1,29 +1,51 @@
local M = {} local M = {}
function M.setup(opts) function M.setup(opts)
local config = require("Polydev.configs") opts = opts or {}
local ui = require("Polydev.ui") local config = require("Polydev.configs")
config.setup(opts) if config == nil then
require("Polydev.utils").setup(opts) return -1
for lang, user_opts in pairs(opts) do end
config.user_config[lang] = vim.tbl_deep_extend("force", config.defaults[lang] or {}, user_opts) config.setup(opts)
end require("Polydev.utils").setup(opts)
vim.api.nvim_create_user_command("PolydevOpen", function() ui.manager(config.get("globals").project_root) end, {}) vim.api.nvim_create_user_command("PolydevOpen", function() require("Polydev.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 {}) local keys = vim.tbl_deep_extend("force", {}, config.get("globals").keybinds, opts.keybinds or {})
for key, _ in pairs(keys) do for key, _ in pairs(keys) do
vim.keymap.set("n", key, ":PolydevOpen<CR>") vim.keymap.set("n", key, ":PolydevOpen<CR>")
end end
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
ui.load_language_module(filetype, opts) require("Polydev.languages").load_language_module(filetype, opts)
end, end,
}) })
vim.api.nvim_create_autocmd("ColorScheme", {
callback = function()
local function define(name, o)
if vim.fn.hlexists(name) == 0 then
vim.api.nvim_set_hl(0, name, o)
end
end
define("PolydevNormal", {
fg = vim.api.nvim_get_hl(0, { name = "NormalFloat", link = true }).fg,
bg = vim.api.nvim_get_hl(0, { name = "Normal", link = true }).bg,
})
define("PolydevBorder", {
fg = vim.api.nvim_get_hl(0, { name = "FloatBorder", link = true }).fg,
bg = vim.api.nvim_get_hl(0, { name = "Normal", link = true }).bg,
})
define("PolydevTitle", {
fg = vim.api.nvim_get_hl(0, { name = "FloatTitle", link = true }).fg, bold = true,
bg = vim.api.nvim_get_hl(0, { name = "Normal", link = true }).bg,
})
end,
})
end end
return M return M
+209 -157
View File
@@ -2,173 +2,225 @@ local utils = require("Polydev.utils")
local configs = require("Polydev.configs") local configs = require("Polydev.configs")
local M = {} local M = {}
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
M.languages = { M.languages = {
java = { javascript = {
setup = function (self, user_opts) setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("java"), user_opts or {}) local opts = vim.tbl_deep_extend("force", {}, configs.get("javascript"), user_opts or {})
vim.api.nvim_create_user_command("JavaRun", function() self:run() end, {}) vim.api.nvim_create_user_command("JavascriptRun", function() self:run() end, {})
for key, _ in pairs(opts.keybinds) do for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":JavaRun<CR>", { silent = true }) vim.keymap.set("n", key, ":JavascriptRun<CR>", { silent = true })
end end
end, end,
run = function () run = function()
local root = utils.get_project_root() local root = utils.get_project_root()
local cmd = string.format("javac -d %s %s", root .. "/build", root .. "/src/*.java") local cmd = string.format("node " .. root .. "/main.js")
local output = vim.fn.system(cmd) local output = vim.fn.system(cmd)
if not vim.v.shell_error == 0 then if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd }) local term_buf = utils.terminal({ cmd })
vim.api.nvim_buf_set_option(term_buf, "modifiable", true) vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true })) vim.list_extend({ "Error during compilation:" },
) vim.split(output, "\n", { trimempty = true }))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false) )
else vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
utils.terminal({ "java -cp " .. root, "build" .. " Main" }) else
end utils.terminal({ "node " .. root .. "/main.js" })
end end
}, end
c = { },
setup = function (self, user_opts) java = {
local opts = vim.tbl_deep_extend("force", {}, configs.get("c"), user_opts or {}) setup = function(self, user_opts)
vim.api.nvim_create_user_command("CRun", function () self:run() end, {}) local opts = vim.tbl_deep_extend("force", {}, configs.get("java"), user_opts or {})
for key, _ in pairs(opts.keybinds) do vim.api.nvim_create_user_command("JavaRun", function() self:run() end, {})
vim.keymap.set("n", key, ":CRun<CR>", { silent = true }) for key, _ in pairs(opts.keybinds) do
end vim.keymap.set("n", key, ":JavaRun<CR>", { silent = true })
end, end
run = function () end,
local root = utils.get_project_root() run = function()
local build_dir = root .. "/build" local root = utils.get_project_root()
local cmd = "cd '" .. build_dir .. "' && cmake --build ." local cmd = string.format("javac -d %s %s", root .. "/build", root .. "/src/*.java")
local output = vim.fn.system(cmd) local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
if not success then if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd }) local term_buf = utils.terminal({ cmd })
vim.api.nvim_buf_set_option(term_buf, "modifiable", true) vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true })) vim.list_extend({ "Error during compilation:" },
) vim.split(output, "\n", { trimempty = true }))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false) )
end vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
if success then else
local run_cmd = "cd '" .. build_dir .. "' && ./" .. utils.get_project_name() utils.terminal({ "java -cp " .. root, "build" .. " Main" })
utils.terminal({ run_cmd }) end
end end
end },
}, c = {
cpp = { setup = function(self, user_opts)
setup = function (self, user_opts) local opts = vim.tbl_deep_extend("force", {}, configs.get("c"), user_opts or {})
local opts = vim.tbl_deep_extend("force", {}, configs.get("cpp"), user_opts or {}) vim.api.nvim_create_user_command("CRun", function() self:run() end, {})
vim.api.nvim_create_user_command("CppRun", function () self:run() end, {}) for key, _ in pairs(opts.keybinds) do
for key, _ in pairs(opts.keybinds) do vim.keymap.set("n", key, ":CRun<CR>", { silent = true })
vim.keymap.set("n", key, ":CppRun<CR>", { silent = true }) end
end end,
end, run = function()
run = function () local root = utils.get_project_root()
local root = utils.get_project_root() local build_dir = root .. "/build"
local build_dir = root .. "/build"
local cmd = "cd '" .. build_dir .. "' && cmake --build ." local cmd = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(cmd) local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0 local success = vim.v.shell_error == 0
if not success then if not success then
local term_buf = utils.terminal({ cmd }) local term_buf = utils.terminal({ cmd })
vim.api.nvim_buf_set_option(term_buf, "modifiable", true) vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true })) vim.list_extend({ "Error during compilation:" },
) vim.split(output, "\n", { trimempty = true }))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false) )
end vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
if success then end
local run_cmd = "cd '" .. build_dir .. "' && ./" .. utils.get_project_name() if success then
utils.terminal({ run_cmd }) local run_cmd = "cd '" .. build_dir .. "' && ./" .. utils.get_project_name()
end utils.terminal({ run_cmd })
end end
}, end
html = { },
setup = function (user_opts) cpp = {
vim.tbl_deep_extend("force", {}, configs.get("html"), user_opts or {}) setup = function(self, user_opts)
end local opts = vim.tbl_deep_extend("force", {}, configs.get("cpp"), user_opts or {})
}, vim.api.nvim_create_user_command("CppRun", function() self:run() end, {})
rust = { for key, _ in pairs(opts.keybinds) do
setup = function (self, user_opts) vim.keymap.set("n", key, ":CppRun<CR>", { silent = true })
local opts = vim.tbl_deep_extend("force", {}, configs.get("rust"), user_opts or {}) end
vim.api.nvim_create_user_command("RustRun", function () self:run() end, {}) end,
for key, _ in pairs(opts.keybinds) do run = function()
vim.keymap.set("n", key, ":RustRun<CR>", { silent = true }) local root = utils.get_project_root()
end local build_dir = root .. "/build"
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 cmd = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(table.concat(cmd)) local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
if not vim.v.shell_error == 0 then if not success then
local term_buf = utils.terminal(cmd) 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() vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
if root then vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
local venv_path = root .. "/venv/bin/activate" vim.list_extend({ "Error during compilation:" },
if vim.fn.filereadable(venv_path) == 1 then vim.split(output, "\n", { trimempty = true }))
vim.env.VIRTUAL_ENV = venv_path )
vim.env.PATH = root .. "/venv/bin:" .. vim.env.PATH vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
end end
end if success then
end, local run_cmd = "cd '" .. build_dir .. "' && ./" .. utils.get_project_name()
install_dependency = function () utils.terminal({ run_cmd })
vim.ui.input({ prompt = "Enter pip module: " }, function(pip_module) end
if not pip_module or pip_module == "" then return print("Pip canceled") end end
utils.terminal({ "pip install " .. pip_module }) },
end) html = {
end, setup = function(user_opts)
run = function () vim.tbl_deep_extend("force", {}, configs.get("html"), user_opts or {})
utils.terminal({ "python3 " .. utils.get_project_root(), "main.py" }) end
end },
}, rust = {
lua = { setup = function(self, user_opts)
setup = function (self, user_opts) local opts = vim.tbl_deep_extend("force", {}, configs.get("rust"), user_opts or {})
local opts = vim.tbl_deep_extend("force", {}, configs.get("lua"), user_opts or {}) vim.api.nvim_create_user_command("RustRun", function() self:run() end, {})
vim.api.nvim_create_user_command("LuaRun", function () self:run() end, {}) for key, _ in pairs(opts.keybinds) do
for key, _ in pairs(opts.keybinds) do vim.keymap.set("n", key, ":RustRun<CR>", { silent = true })
vim.keymap.set("n", key, ":LuaRun<CR>", { silent = true }) end
end end,
end, run = function()
run = function () local root = utils.get_project_root()
local init_lua_path = utils.get_project_root() .. "/lua/" .. utils.get_project_name() .. "/init.lua" if not root then return print("Error: Project root not found.") end
if vim.fn.filereadable(init_lua_path) == 1 then
utils.terminal({ "lua " .. init_lua_path }) local cmd = { "cargo build" }
end local output = vim.fn.system(table.concat(cmd))
end
}, if not vim.v.shell_error == 0 then
local term_buf = utils.terminal(cmd)
vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
else
utils.terminal({ "cargo run" })
end
end
},
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 return M
+11 -20
View File
@@ -1,35 +1,26 @@
local M = {} 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 = { local presets = {
right = { right = {
left_padding = 100, left = 100,
right_padding = 0, right = 0,
top_padding = 0, top = 0,
bottom_padding = 0, bottom = 0,
}, },
corner = { corner = {
left_padding = 100, left = 100,
right_padding = 0, right = 0,
top_padding = 25, top = 25,
bottom_padding = 0, bottom = 0,
} }
} }
---@param preset string ---@param preset string
---@return table|nil ---@return table|nil
function M.getPresets(preset) function M.getPresets(preset)
return presets[preset] if presets[preset] then
return presets[preset]
end
end end
return M return M
-23
View File
@@ -1,23 +0,0 @@
local M = {}
function M.setup_highlights()
-- Only set if not already defined by colorscheme
local function define(name, opts)
if vim.fn.hlexists(name) == 0 then
vim.api.nvim_set_hl(0, name, opts)
end
end
define("PolydevNormal", {
fg = vim.api.nvim_get_hl_by_name("NormalFloat", true).foreground,
bg = vim.api.nvim_get_hl_by_name("Normal", true).background
})
define("PolydevBorder", {
fg = vim.api.nvim_get_hl_by_name("Function", true).foreground,
bg = vim.api.nvim_get_hl_by_name("Normal", true).background
})
define("PolydevTitle", { fg = "#89dceb", bold = true })
end
return M
+274 -158
View File
@@ -3,9 +3,9 @@ local utils = require("Polydev.utils")
local M = {} local M = {}
local function extras(guard, file_type, file_name) local function extras(guard, file_type, file_name)
if not file_name then return print("Header file creation canceled") end if not file_name then return print("Header file creation canceled") end
local guard_macro = file_name:upper():gsub("[^A-Z0-9]", "_") .. guard local guard_macro = file_name:upper():gsub("[^A-Z0-9]", "_") .. guard
local content = string.format([[ local content = string.format([[
#ifndef %s #ifndef %s
#define %s #define %s
@@ -13,56 +13,68 @@ local function extras(guard, file_type, file_name)
#endif #endif
]], guard_macro, guard_macro) ]], guard_macro, guard_macro)
utils.write_file({ utils.get_project_root(), "include", file_name .. file_type }, content) utils.write_file({ utils.get_project_root(), "include", file_name .. file_type }, content)
end end
M.projects = { M.projects = {
lua = { javascript = {
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 .. "/lua/" .. project_name, "p") vim.fn.mkdir(full_project_root, "p")
utils.write_file({ full_project_root, "lua", project_name, "init.lua" }, [[ utils.write_file({ full_project_root, "main.js" }, [[
console.log("Hello World!");
]])
local gitignore = { "" }
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/main.js")
end
},
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 = {} local M = {}
return M return M
]]) ]])
local gitignore = { "" } local gitignore = { "" }
utils.init_git(full_project_root, gitignore) utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/lua/" .. project_name .. "/init.lua") vim.cmd("edit " .. full_project_root .. "/lua/" .. project_name .. "/init.lua")
end 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 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!");
} }
} }
]] ]]
local gitignore = { local gitignore = {
"build/" "build/"
} }
utils.init_git(full_project_root, gitignore) utils.init_git(full_project_root, gitignore)
utils.write_file({ full_project_root, "src", "Main.java" }, content) 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(
@@ -73,98 +85,200 @@ setup(
python_requires=">=3.6", python_requires=">=3.6",
) )
]], project_name)) ]], project_name))
local gitignore = { local gitignore = {
"venv/" "venv/"
} }
utils.init_git(full_project_root, gitignore) 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)
vim.g.python3_host_prog = venv_path .. "/bin/python" vim.g.python3_host_prog = venv_path .. "/bin/python"
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)
end end
}, },
c = { c = {
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", "/include" }) do vim.fn.mkdir(full_project_root .. path, "p") end for _, path in ipairs({ "/src", "/build", "/include" }) do
utils.write_file({ full_project_root, "src/main.c" }, [[ vim.fn.mkdir(
full_project_root .. path, "p")
end
utils.write_file({ full_project_root, ".clang-format" }, [[
---
BasedOnStyle: Google
Standard: Latest
UseTab: Always
TabWidth: 8
IndentWidth: 8
BreakBeforeBraces: Allman
SpaceBeforeCpp11BracedList: true
SeparateDefinitionBlocks: Always
Cpp11BracedListStyle: false
BreakAfterReturnType: TopLevel
AlignTrailingComments:
Kind: Always
ReflowComments: Always
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
IndentAccessModifiers: false # Indent access specifiers by one level
AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level
]])
utils.write_file({ full_project_root, "src/main.c" }, [[
#include <stdio.h> #include <stdio.h>
int main() { int main() {
printf("%s", "Hello World"); printf("%s", "Hello World");
return 0; return 0;
} }
]]) ]])
utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.10) utils.write_file({ full_project_root, ".clang-tidy" }, string.format([[
project(%s) ---
include_directories(include) Checks: >
set(SOURCES src/main.c) -*,
add_executable(%s ${SOURCES}) bugprone-*,
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) concurrency-*,
misc-*,
modernize-*,
performance-*,
readability-*,
portability-*,
-readability-braces-around-statements,
-readability-implicit-bool-conversion
WarningsAsErrors: ""
CheckOptions:
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.FunctionCase
value: lower_case
---
]]))
utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.16)
set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include_directories(include)
project(%s LANGUAGES C)
# find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg set(SOURCES
# target_link_libraries(Game PRIVATE SDL3::SDL3) src/main.c
]], project_name, project_name)) )
local gitignore = { "build/" }
utils.init_git(full_project_root, gitignore) add_executable(%s ${SOURCES})
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)) ]], project_name, project_name, project_name))
vim.cmd("edit " .. full_project_root .. "/src/main.c") local gitignore = { "build/", ".cache/" }
end utils.init_git(full_project_root, gitignore)
}, vim.fn.system(string.format(
cpp = { "cd %s/build && cmake -S .. -B . && cmake --build . && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..",
run = function (project_name, project_root) full_project_root))
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name vim.cmd("edit " .. full_project_root .. "/src/main.c")
for _, path in ipairs({ "/src", "/build", "/include" }) do end
vim.fn.mkdir(full_project_root .. path, "p") },
end cpp = {
utils.write_file({ full_project_root, "src/main.cpp" }, [[ run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build", "/include" }) do
vim.fn.mkdir(full_project_root .. path, "p")
end
utils.write_file({ full_project_root, ".clang-format" }, [[
---
BasedOnStyle: Google
Standard: Latest
UseTab: Always
TabWidth: 8
IndentWidth: 8
BreakBeforeBraces: Allman
SpaceBeforeCpp11BracedList: true
SeparateDefinitionBlocks: Always
Cpp11BracedListStyle: false
BreakAfterReturnType: TopLevel
AlignTrailingComments:
Kind: Always
ReflowComments: Always
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
IndentAccessModifiers: false # Indent access specifiers by one level
AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level
]])
utils.write_file({ full_project_root, "src/main.cpp" }, [[
#include <iostream> #include <iostream>
int main() { int main() {
std::cout << "Hello World" << std::endl; std::cout << "Hello World\n";
return 0; return 0;
} }
]]) ]])
utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.10)
project(%s)
include_directories(include)
set(SOURCES src/main.cpp)
add_executable(%s ${SOURCES})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
# find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg utils.write_file({ full_project_root, ".clang-tidy" }, string.format([[
# target_link_libraries(Game PRIVATE SDL3::SDL3) ---
Checks: >
-*,
bugprone-*,
concurrency-*,
misc-*,
modernize-*,
performance-*,
readability-*,
portability-*,
-readability-braces-around-statements,
-readability-implicit-bool-conversion
WarningsAsErrors: ""
CheckOptions:
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.FunctionCase
value: lower_case
---
]]))
utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(%s LANGUAGES CXX)
set(SOURCES
src/main.cpp
)
add_executable(%s ${SOURCES})
]], project_name, project_name)) ]], project_name, project_name))
local gitignore = { "build/" } local gitignore = { "build/", ".cache/" }
utils.init_git(full_project_root, gitignore) 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.fn.system(string.format(
vim.cmd("edit " .. full_project_root .. "/src/main.cpp") "cd %s/build && cmake -S .. -B . && cmake --build . && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..",
end full_project_root))
}, vim.cmd("edit " .. full_project_root .. "/src/main.cpp")
rust = { end
run = function (project_name, project_root) },
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name rust = {
vim.fn.system("cargo new " .. full_project_root) run = function(project_name, project_root)
vim.cmd("edit " .. full_project_root .. "/src/main.rs") local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
end vim.fn.system("cargo new " .. full_project_root)
}, vim.cmd("edit " .. full_project_root .. "/src/main.rs")
html = { end
run = function(project_name, project_root) },
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name html = {
if vim.fn.isdirectory(full_project_root) == 0 then run = function(project_name, project_root)
vim.fn.mkdir(full_project_root, "p") -- Create directory with parent directories local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
end if vim.fn.isdirectory(full_project_root) == 0 then
local main_html_content = [[ vim.fn.mkdir(full_project_root, "p") -- Create directory with parent directories
end
local main_html_content = [[
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
@@ -178,50 +292,51 @@ 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
}, },
} }
M.files = { M.files = {
lua = { lua = {
run = function (file_name) run = function(file_name)
utils.write_file({ utils.get_project_root(), "lua", utils.get_project_name(), file_name .. ".lua"}, "") utils.write_file(
end { utils.get_project_root(), "lua", utils.get_project_name(), file_name .. ".lua" }, "")
}, end
java = { },
run = function (file_name) java = {
utils.write_file({ utils.get_project_root(), "src", file_name .. ".java" }, string.format([[ run = function(file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".java" }, string.format([[
public class %s { public class %s {
// New File // New File
} }
]], file_name)) ]], file_name))
end end
}, },
python = { python = {
run = function (file_name) run = function(file_name)
utils.write_file({ utils.get_project_root(), "include", file_name .. ".py" }, "") utils.write_file({ utils.get_project_root(), "include", file_name .. ".py" }, "")
end end
}, },
c = { c = {
run = function (file_name) run = function(file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".c" }, "") utils.write_file({ utils.get_project_root(), "src", file_name .. ".c" }, "")
end end
}, },
cpp = { cpp = {
run = function (file_name) run = function(file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".cpp" }, "") utils.write_file({ utils.get_project_root(), "src", file_name .. ".cpp" }, "")
end end
}, },
rust = { rust = {
run = function (file_name) run = function(file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".rs" }, "") utils.write_file({ utils.get_project_root(), "src", file_name .. ".rs" }, "")
end end
}, },
html = { html = {
run = function (file_name) run = function(file_name)
utils.write_file({ ".", file_name .. ".html" }, string.format([[ utils.write_file({ ".", file_name .. ".html" }, string.format([[
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
@@ -235,21 +350,22 @@ public class %s {
</body> </body>
</html> </html>
]])) ]]))
end end
} }
} }
M.extras = { M.extras = {
run = function (lang, file_name) run = function(lang, file_name)
if lang == "c" then if lang == "c" then
extras("_H", ".h", file_name) extras("_H", ".h", file_name)
print("Successful creation of " .. file_name .. ".h") print("Successful creation of " .. file_name .. ".h")
end elseif lang == "cpp" then
if lang == "cpp" then extras("_HPP", ".hpp", file_name)
extras("_HPP", ".hpp", file_name) print("Successful creation of " .. file_name .. ".hpp")
print("Successful creation of " .. file_name .. ".hpp") else
end print("Extras language is not found: enter cpp or c")
end end
end
} }
return M return M
+161 -376
View File
@@ -3,402 +3,187 @@ local M = {}
---@param path string ---@param path string
---@return table ---@return table
local function get_entries(path) local function get_entries(path)
local result = {} local result = {}
local handle = vim.loop.fs_scandir(path) local handle = vim.uv.fs_scandir(path)
if not handle then return result end if not handle then return result end
while true do while true do
local name, type = vim.loop.fs_scandir_next(handle) local name, type = vim.uv.fs_scandir_next(handle)
if not name then break end if not name then break end
-- Check if this is a project file table.insert(result, {
local is_project = false name = name .. (type == "directory" and "/" or ""),
if type == "file" then type = type,
local ext = name:match("%.([^%.]+)$") full_path = path .. "/" .. name,
if ext == "project" then })
is_project = true
type = "project"
end
end end
table.insert(result, { table.sort(result, function(a, b)
name = name .. (type == "directory" and "/" or ""), if a.type == "directory" and b.type ~= "directory" then return true end
type = type, if b.type == "directory" and a.type ~= "directory" then return false end
full_path = path .. "/" .. name, return a.name < b.name
is_project = is_project end)
}) return result
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 end
---@param project_root string ---@param project_root string
function M.manager(project_root) function M.manager(project_root)
local templates = require("Polydev.templates") local templates = require("Polydev.templates")
local Popup = require("nui.popup") local width, height = math.floor(vim.o.columns * 0.40), math.floor(vim.o.lines * 0.4)
local Layout = require("nui.layout") local row, col = math.floor((vim.o.lines - height) / 3), math.floor((vim.o.columns - width) / 2)
local event = require("nui.utils.autocmd").event local content_row = row + 2
local cwd = vim.fn.expand(vim.fn.getcwd()) local content_height = height - 3
local entries = get_entries(cwd)
local current_view = vim.deepcopy(entries)
-- Create a new custom highlight group with Normal background and NormalFloat foreground local cwd = vim.fn.getcwd()
vim.api.nvim_set_hl(0, "CustomFloatText", { local current_view = {}
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({ local content_buf = vim.api.nvim_create_buf(false, true)
enter = true, local content_win = vim.api.nvim_open_win(content_buf, true, {
focusable = true, relative = "editor",
border = { width = width,
style = "rounded", -- "double", "none", "rounded", "shadow", "single" or "solid". height = content_height,
text = { top = " Results ", top_align = "center" }, row = content_row,
}, col = col,
position = "50%", style = "minimal",
buf_options = { modifiable = true, readonly = false }, border = "rounded",
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 function close_all_windows()
local row = vim.api.nvim_win_get_cursor(popup.winid)[1] - 1 if vim.api.nvim_win_is_valid(content_win) then
return current_view[row], row pcall(vim.api.nvim_win_close, content_win, true)
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 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 end
-- Only add ".." if we're inside Projects and not at the root local function update_screen()
if cwd ~= root then local root = vim.fn.expand(project_root)
table.insert(entries, 1, { if vim.fn.isdirectory(root) == 0 then
name = "../", vim.fn.mkdir(root, "p")
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) local entries = get_entries(cwd)
end if not cwd:find(root, 1, true) then
end) cwd = root
entries = get_entries(cwd)
-- 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) 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)
local lines = {}
if #current_view == 0 then
table.insert(lines, "No projects found in " .. cwd)
table.insert(lines, "Press d to create a project, or a to add a folder.")
else
for i, item in ipairs(current_view) do
table.insert(lines, string.format("%-2d | %-27s | %-6s", i, item.name, item.type))
end
end
vim.api.nvim_buf_set_lines(content_buf, 0, -1, false, lines)
end end
end)
-- Changes working directory or edits a file local function get_selected_entry()
popup:map("n", "<CR>", function() local win = content_win
local entry = get_selected_entry() if not win or not vim.api.nvim_win_is_valid(win) then return end
if entry.type == "directory" then local row = vim.api.nvim_win_get_cursor(win)[1]
cwd = entry.full_path return current_view[row], row
vim.cmd("cd " .. cwd)
refresh()
render()
end end
if entry.type == "file" then
popup:unmount() ---@param type string
vim.schedule(function() ---@param callback fun(lang: string, name: string)
vim.cmd("edit " .. vim.fn.fnameescape(entry.full_path)) local function get_inputs(type, callback)
end) vim.ui.input({ prompt = "Enter language for new " .. type .. ": " }, function(lang)
if not lang or lang == "" then return end
vim.ui.input({ prompt = "Enter " .. type .. " name: " }, function(name)
if not name or name == "" then return end
callback(lang, name)
end)
end)
end end
end)
popup:map("n", "<BS>", function() update_screen()
local parent = vim.fn.fnamemodify(cwd, ":h")
if parent ~= cwd then
cwd = parent
refresh()
render()
end
end)
popup:on(event.BufLeave, function() local buf = content_buf
vim.defer_fn(function() vim.keymap.set("n", "<ESC>", function()
local function is_valid_win(winid) if vim.api.nvim_win_is_valid(content_win) then
return type(winid) == "number" and vim.api.nvim_win_is_valid(winid) pcall(vim.api.nvim_win_close, content_win, true)
end end
end, { buffer = buf })
vim.keymap.set("n", "a", function ()
vim.ui.input({ prompt = "New folder name: " }, function(input)
if input then
vim.fn.mkdir(cwd .. "/" .. input, "p")
update_screen()
end
end)
end, { buffer = buf })
vim.keymap.set("n", "R", function ()
local entry = get_selected_entry()
if entry ~= nil and 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)
update_screen()
end
end)
end
end, { buffer = buf })
vim.keymap.set("n", "D", function()
local entry = get_selected_entry()
if entry ~= nil and 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")
update_screen()
end
end)
end
end, { buffer = buf })
vim.keymap.set("n", "%", function()
get_inputs("file", function(lang, name)
local file = templates.files[lang]
if not file or not file.run then
return print("Error: No file creation method for " .. lang)
end
close_all_windows()
file.run(name)
end)
end, { buffer = buf })
vim.keymap.set("n", "x", function()
get_inputs("aux file", function(lang, name)
close_all_windows()
templates.extras.run(lang, name)
end)
end, { buffer = buf })
vim.keymap.set("n", "d", function()
get_inputs("project", function(lang, name)
local project = templates.projects[lang]
if not project or not project.run then
return print("Error: No project creation method for " .. lang)
end
local opts = require("Polydev.configs").get(lang)
local run_root = opts.project_root or project_root
close_all_windows()
project.run(name, run_root)
end)
end, { buffer = buf })
vim.keymap.set("n", "<CR>", function()
local entry = get_selected_entry()
if not entry then return end
if not is_valid_win(popup.winid) and not is_valid_win(search.winid) then if entry.type == "file" then
popup:unmount() close_all_windows()
end vim.cmd("edit " .. vim.fn.fnameescape(entry.full_path))
end, 50) elseif entry.type == "directory" then
end) cwd = entry.full_path
vim.cmd("cd " .. cwd)
popup:mount() update_screen()
refresh() else
render() print("Error")
end
end, { buffer = buf })
end end
return M return M
+78 -59
View File
@@ -2,94 +2,113 @@ 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
---@param path string function M.exists(path)
---@return boolean|nil return (io.open(path, "r") ~= nil)
function M.is_dir(path)
local stat = vim.loop.fs_stat(path)
return stat and stat.type == "directory"
end end
---@return string ---@return string
function M.get_project_root() function M.get_project_root()
local plugin_dir = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":h:h:h") 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+$", "") local dir = vim.fn.system(plugin_dir .. "/bash_scripts/walkup.sh"):gsub("%s+$", "")
return dir return dir
end end
---@return string ---@return string
function M.get_project_name() function M.get_project_name()
local root = M.get_project_root() return vim.fn.fnamemodify(M.get_project_root(), ":t")
return vim.fn.fnamemodify(root, ":t")
end end
---@param path_segments table ---@param path_segments table
---@param content string ---@param content string
function M.write_file(path_segments, content) function M.write_file(path_segments, content)
local path = table.concat(path_segments, "/") 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)
end end
---@param path string ---@param path string
---@param gitignore_lines table ---@param gitignore_lines table
function M.init_git(path, gitignore_lines) function M.init_git(path, gitignore_lines)
vim.fn.mkdir(path, "p") vim.fn.mkdir(path, "p")
vim.fn.system({ "git", "-C", path, "init" }) vim.fn.system({ "git", "-C", path, "init" })
if gitignore_lines and #gitignore_lines > 0 then if gitignore_lines and #gitignore_lines > 0 then
local gitignore_path = { path, ".gitignore" } local contents = table.concat(gitignore_lines, "\n")
local contents = table.concat(gitignore_lines, "\n") M.write_file({ path, ".gitignore" }, contents)
M.write_file(gitignore_path, contents) end
end
end end
---@param cmd table ---@param cmd table
---@return integer, integer ---@return integer, integer?
function M.terminal(cmd) function M.terminal(cmd)
local opts = require("Polydev.presets").getPresets(M.opts.preset) if M.opts.mode == "floating" then
local ui = vim.api.nvim_list_uis()[1] local opts = require("Polydev.presets").getPresets(M.opts.win.anchor)
local width
local height
local row
local col
if opts ~= nil then local ui = vim.api.nvim_list_uis()[1]
width = math.max(1, math.floor(ui.width * 0.9) - opts.left_padding - opts.right_padding) local width, height, row, col
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) if opts ~= nil then
local win = vim.api.nvim_open_win(buf, true, { width = math.max(1, math.floor(ui.width * 0.9) - opts.left - opts.right)
relative = "editor", height = math.max(1, math.floor(ui.height * 0.9) - opts.top - opts.bottom)
width = width, row = math.floor((ui.height - height) / 2) + opts.top
height = height, col = math.floor((ui.width - width) / 2) + opts.left
row = row, end
col = col, if opts == nil then
style = "minimal", width = math.max(1, math.floor(ui.width * 0.9))
border = M.opts.border.enabled and M.opts.border.type, height = math.max(1, math.floor(ui.height * 0.9))
}) row = math.floor((ui.height - height) / 2)
vim.api.nvim_set_option_value("winblend", vim.o.pumblend, { win = win }) col = math.floor((ui.width - width) / 2)
vim.api.nvim_set_option_value("winhighlight", "Normal:Pmenu,FloatBorder:Pmenu", { win = win }) end
vim.api.nvim_set_option_value("cursorline", true, { win = win }) local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_set_option_value("scrolloff", 5, { win = win }) local win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = M.opts.border.enabled and M.opts.border.type,
})
vim.api.nvim_set_option_value("winhighlight", "Normal:PolydevNormal,FloatBorder:PolydevBorder",
{ win = win })
vim.fn.jobstart(table.concat(cmd, "/"), { term = true })
vim.api.nvim_buf_set_keymap(buf, "n", "<ESC>", "i<C-\\><C-n>:q<CR>", { noremap = true, silent = true })
return buf, win
end
if M.opts.mode == "split" then
if M.opts.win.type == "vertical" then
if M.opts.win.anchor == "right" then
vim.cmd("set splitright")
end
end
if M.opts.win.type == "horizontal" then
if M.opts.win.anchor == "bottom" then
vim.cmd("set splitbelow")
end
end
vim.fn.termopen(table.concat(cmd, "/")) if M.opts.win.type == "vertical" then
vim.api.nvim_buf_set_keymap(buf, "n", "<ESC>", "i<C-\\><C-n>:q<CR>", { noremap = true, silent = true }) vim.cmd(M.opts.win.size .. " vsplit")
return buf, win end
if M.opts.win.type == "horizontal" then
vim.cmd(M.opts.win.size .. " split")
end
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_buf(0, buf)
vim.fn.jobstart(table.concat(cmd, "/"), { term = true })
vim.api.nvim_buf_set_keymap(buf, "n", "<ESC>", "i<C-\\><C-n>:q<CR>", { noremap = true, silent = true })
return buf, win
end
return 0
end end
return M return M
-55
View File
@@ -1,55 +0,0 @@
site_name: Polydev
nav:
- Home: index.md
- Installation: installation.md
- Setup: setup.md
- Language Specific Docs:
- Java: languages/java.md
- C: languages/c.md
- Cpp: languages/cpp.md
- Lua: languages/lua.md
- Python: languages/python.md
- Rust: languages/rust.md
- Html: languages/html.md
theme:
name: material
features:
- navigation.tabs
- navigation.sections
- toc.integrate
- navigation.top
- search.suggest
- search.highlight
- content.tabs.link
- content.code.annotation
- content.code.copy
language: en
palette:
- scheme: slate
primary: slate
accent: teal
extra:
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/DarthMooMancer
markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.inlinehilite
- pymdownx.snippets
- admonition
- pymdownx.arithmatex:
generic: true
- footnotes
- pymdownx.details
- pymdownx.superfences
- pymdownx.mark
- attr_list
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
copyright: |
&copy; 2025 <a href="https://github.com/DarthMooMancer" target="_blank" rel="noopener">DarthMooMancer</a>
+1
View File
@@ -0,0 +1 @@
require("Polydev").setup()