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
Lua_Annotation_CheatSheet/
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>
<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">
<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>
## Features
@@ -23,9 +19,9 @@
* Integrated terminal for flexible command execution
* Lightweight, fast project manager UI
* 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
@@ -45,8 +41,7 @@ Additional language support is planned for future releases.
Current focus:
* **Refactoring and internal cleanup.**
Feature additions will resume after this phase.
* **Remaking it not in nui to make tabs, mainly for recent projects as the main page**
## 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 = {}
M.defaults = {
globals = {
project_root = "~/Projects",
keybinds = {
["<leader>po"] = "PolydevManager",
},
},
terminal = {
preset = nil,
border = {
enabled = true,
type = "rounded",
},
},
}
local function default_languages(project_root)
return {
rust = {
project_root = project_root .. "/Rust",
keybinds = {
["<leader>pr"] = "RustRun",
},
},
java = {
project_root = project_root .. "/Java",
keybinds = {
["<leader>pr"] = "JavaRun",
},
},
lua = {
project_root = project_root .. "/Lua",
keybinds = {
["<leader>pr"] = "LuaRun",
},
},
c = {
project_root = project_root .. "/C",
keybinds = {
["<leader>pr"] = "CRun",
},
},
cpp = {
project_root = project_root .. "/CPP",
keybinds = {
["<leader>pr"] = "CppRun",
},
},
html = {
project_root = project_root .. "/Html",
},
}
end
M.user_config = {}
---@param user_opts table
function M.setup(user_opts)
-- First merge global and terminal
M.user_config = vim.tbl_deep_extend("force", {}, M.defaults, user_opts or {})
user_opts = 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
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
M.user_config = vim.tbl_deep_extend("force", defaults, user_opts)
end
---@param lang string
---@return table
function M.get(lang)
return M.user_config[lang] or {}
return M.user_config[lang] or {}
end
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 = {}
function M.setup(opts)
local config = require("Polydev.configs")
local ui = require("Polydev.ui")
config.setup(opts)
require("Polydev.utils").setup(opts)
for lang, user_opts in pairs(opts) do
config.user_config[lang] = vim.tbl_deep_extend("force", config.defaults[lang] or {}, user_opts)
end
opts = opts or {}
local config = require("Polydev.configs")
if config == nil then
return -1
end
config.setup(opts)
require("Polydev.utils").setup(opts)
vim.api.nvim_create_user_command("PolydevOpen", function() ui.manager(config.get("globals").project_root) end, {})
-- require("Polydev.styles").setup_highlights()
vim.api.nvim_create_user_command("PolydevOpen", function() require("Polydev.ui").manager(config.get("globals").project_root) end, {})
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
local keys = vim.tbl_deep_extend("force", {}, config.get("globals").keybinds, opts.keybinds or {})
for key, _ in pairs(keys) do
vim.keymap.set("n", key, ":PolydevOpen<CR>")
end
vim.api.nvim_create_autocmd("FileType", {
pattern = "*",
callback = function()
local filetype = vim.bo.filetype
ui.load_language_module(filetype, opts)
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = "*",
callback = function()
local filetype = vim.bo.filetype
require("Polydev.languages").load_language_module(filetype, opts)
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
return M
+209 -157
View File
@@ -2,173 +2,225 @@ local utils = require("Polydev.utils")
local configs = require("Polydev.configs")
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 = {
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()
javascript = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("javascript"), user_opts or {})
vim.api.nvim_create_user_command("JavascriptRun", function() self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":JavascriptRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
local cmd = string.format("javac -d %s %s", root .. "/build", root .. "/src/*.java")
local output = vim.fn.system(cmd)
local cmd = string.format("node " .. root .. "/main.js")
local output = vim.fn.system(cmd)
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_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"
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
else
utils.terminal({ "node " .. root .. "/main.js" })
end
end
},
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 = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
local cmd = string.format("javac -d %s %s", root .. "/build", root .. "/src/*.java")
local output = vim.fn.system(cmd)
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"
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({ "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
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
if not success 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 })
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 = { "cargo build" }
local output = vim.fn.system(table.concat(cmd))
local cmd = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
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
if not success then
local term_buf = utils.terminal({ cmd })
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
},
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 })
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_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
+11 -20
View File
@@ -1,35 +1,26 @@
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,
left = 100,
right = 0,
top = 0,
bottom = 0,
},
corner = {
left_padding = 100,
right_padding = 0,
top_padding = 25,
bottom_padding = 0,
left = 100,
right = 0,
top = 25,
bottom = 0,
}
}
---@param preset string
---@return table|nil
function M.getPresets(preset)
return presets[preset]
if presets[preset] then
return presets[preset]
end
end
return M
-23
View File
@@ -1,23 +0,0 @@
local M = {}
function M.setup_highlights()
-- Only set if not already defined by colorscheme
local function define(name, opts)
if vim.fn.hlexists(name) == 0 then
vim.api.nvim_set_hl(0, name, opts)
end
end
define("PolydevNormal", {
fg = vim.api.nvim_get_hl_by_name("NormalFloat", true).foreground,
bg = vim.api.nvim_get_hl_by_name("Normal", true).background
})
define("PolydevBorder", {
fg = vim.api.nvim_get_hl_by_name("Function", true).foreground,
bg = vim.api.nvim_get_hl_by_name("Normal", true).background
})
define("PolydevTitle", { fg = "#89dceb", bold = true })
end
return M
+274 -158
View File
@@ -3,9 +3,9 @@ local utils = require("Polydev.utils")
local M = {}
local function extras(guard, file_type, file_name)
if not file_name then return print("Header file creation canceled") end
local guard_macro = file_name:upper():gsub("[^A-Z0-9]", "_") .. guard
local content = string.format([[
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
@@ -13,56 +13,68 @@ local function extras(guard, file_type, file_name)
#endif
]], 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
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" }, [[
javascript = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.mkdir(full_project_root, "p")
utils.write_file({ full_project_root, "main.js" }, [[
console.log("Hello World!");
]])
local gitignore = { "" }
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/main.js")
end
},
lua = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.mkdir(full_project_root .. "/lua/" .. project_name, "p")
utils.write_file({ full_project_root, "lua", project_name, "init.lua" }, [[
local M = {}
return M
]])
local gitignore = { "" }
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/lua/" .. project_name .. "/init.lua")
end
},
java = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build" }) do vim.fn.mkdir(full_project_root .. path, "p") end
local content = [[
local gitignore = { "" }
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/lua/" .. project_name .. "/init.lua")
end
},
java = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build" }) do vim.fn.mkdir(full_project_root .. path, "p") end
local content = [[
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
]]
local gitignore = {
"build/"
}
utils.init_git(full_project_root, gitignore)
utils.write_file({ full_project_root, "src", "Main.java" }, content)
end
},
python = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.mkdir(full_project_root .. "/include", "p")
utils.write_file({ full_project_root, "main.py" }, [[
local gitignore = {
"build/"
}
utils.init_git(full_project_root, gitignore)
utils.write_file({ full_project_root, "src", "Main.java" }, content)
end
},
python = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.mkdir(full_project_root .. "/include", "p")
utils.write_file({ full_project_root, "main.py" }, [[
def main():
print("Hello, World!")
if __name__ == "__main__":
main()
]])
utils.write_file({ full_project_root, "include/__init__.py" }, "")
utils.write_file({ full_project_root, "requirements.txt" }, "")
utils.write_file({ full_project_root, "setup.py" }, string.format([[
utils.write_file({ full_project_root, "include/__init__.py" }, "")
utils.write_file({ full_project_root, "requirements.txt" }, "")
utils.write_file({ full_project_root, "setup.py" }, string.format([[
from setuptools import setup, find_packages
setup(
@@ -73,98 +85,200 @@ setup(
python_requires=">=3.6",
)
]], project_name))
local gitignore = {
"venv/"
}
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/main.py")
local venv_path = full_project_root .. "/venv"
vim.fn.system("python3 -m venv " .. venv_path)
vim.g.python3_host_prog = venv_path .. "/bin/python"
vim.fn.setenv("VIRTUAL_ENV", venv_path)
vim.fn.setenv("PATH", venv_path .. "/bin:" .. vim.fn.getenv("PATH"))
print("Virtual environment activated for " .. project_name)
end
},
c = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build", "/include" }) do vim.fn.mkdir(full_project_root .. path, "p") end
utils.write_file({ full_project_root, "src/main.c" }, [[
local gitignore = {
"venv/"
}
utils.init_git(full_project_root, gitignore)
vim.cmd("edit " .. full_project_root .. "/main.py")
local venv_path = full_project_root .. "/venv"
vim.fn.system("python3 -m venv " .. venv_path)
vim.g.python3_host_prog = venv_path .. "/bin/python"
vim.fn.setenv("VIRTUAL_ENV", venv_path)
vim.fn.setenv("PATH", venv_path .. "/bin:" .. vim.fn.getenv("PATH"))
print("Virtual environment activated for " .. project_name)
end
},
c = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build", "/include" }) do
vim.fn.mkdir(
full_project_root .. path, "p")
end
utils.write_file({ full_project_root, ".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>
int main() {
printf("%s", "Hello World");
return 0;
printf("%s", "Hello World");
return 0;
}
]])
utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.10)
project(%s)
include_directories(include)
set(SOURCES src/main.c)
add_executable(%s ${SOURCES})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
utils.write_file({ full_project_root, ".clang-tidy" }, string.format([[
---
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_C_STANDARD 23)
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
# target_link_libraries(Game PRIVATE SDL3::SDL3)
]], project_name, project_name))
local gitignore = { "build/" }
utils.init_git(full_project_root, gitignore)
vim.fn.system(string.format("cd %s/build && cmake -S .. -B . && cmake --build . && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. && ln -sf compile_commands.json ../compile_commands.json", full_project_root))
vim.cmd("edit " .. full_project_root .. "/src/main.c")
end
},
cpp = {
run = function (project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build", "/include" }) do
vim.fn.mkdir(full_project_root .. path, "p")
end
utils.write_file({ full_project_root, "src/main.cpp" }, [[
set(SOURCES
src/main.c
)
add_executable(%s ${SOURCES})
]], project_name, project_name, project_name))
local gitignore = { "build/", ".cache/" }
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 ..",
full_project_root))
vim.cmd("edit " .. full_project_root .. "/src/main.c")
end
},
cpp = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
for _, path in ipairs({ "/src", "/build", "/include" }) do
vim.fn.mkdir(full_project_root .. path, "p")
end
utils.write_file({ full_project_root, ".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>
int main() {
std::cout << "Hello World" << std::endl;
return 0;
std::cout << "Hello World\n";
return 0;
}
]])
utils.write_file({ full_project_root, "CMakeLists.txt" }, string.format([[
cmake_minimum_required(VERSION 3.10)
project(%s)
include_directories(include)
set(SOURCES src/main.cpp)
add_executable(%s ${SOURCES})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
# find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg
# target_link_libraries(Game PRIVATE SDL3::SDL3)
utils.write_file({ full_project_root, ".clang-tidy" }, string.format([[
---
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))
local gitignore = { "build/" }
utils.init_git(full_project_root, gitignore)
vim.fn.system(string.format("cd %s/build && cmake -S .. -B . && cmake --build . && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. && ln -sf compile_commands.json ../compile_commands.json", full_project_root))
vim.cmd("edit " .. full_project_root .. "/src/main.cpp")
end
},
rust = {
run = function (project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.system("cargo new " .. full_project_root)
vim.cmd("edit " .. full_project_root .. "/src/main.rs")
end
},
html = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
if vim.fn.isdirectory(full_project_root) == 0 then
vim.fn.mkdir(full_project_root, "p") -- Create directory with parent directories
end
local main_html_content = [[
local gitignore = { "build/", ".cache/" }
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 ..",
full_project_root))
vim.cmd("edit " .. full_project_root .. "/src/main.cpp")
end
},
rust = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
vim.fn.system("cargo new " .. full_project_root)
vim.cmd("edit " .. full_project_root .. "/src/main.rs")
end
},
html = {
run = function(project_name, project_root)
local full_project_root = vim.fn.expand(project_root) .. "/" .. project_name
if vim.fn.isdirectory(full_project_root) == 0 then
vim.fn.mkdir(full_project_root, "p") -- Create directory with parent directories
end
local main_html_content = [[
<!DOCTYPE html>
<html>
<head>
@@ -178,50 +292,51 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
</body>
</html>
]]
utils.write_file({ full_project_root, "index.html" }, main_html_content)
end
},
utils.write_file({ full_project_root, "index.html" }, main_html_content)
end
},
}
M.files = {
lua = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "lua", utils.get_project_name(), file_name .. ".lua"}, "")
end
},
java = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".java" }, string.format([[
lua = {
run = function(file_name)
utils.write_file(
{ utils.get_project_root(), "lua", utils.get_project_name(), file_name .. ".lua" }, "")
end
},
java = {
run = function(file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".java" }, string.format([[
public class %s {
// New File
}
]], file_name))
end
},
python = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "include", file_name .. ".py" }, "")
end
},
c = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".c" }, "")
end
end
},
python = {
run = function(file_name)
utils.write_file({ utils.get_project_root(), "include", file_name .. ".py" }, "")
end
},
c = {
run = function(file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".c" }, "")
end
},
cpp = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".cpp" }, "")
end
},
rust = {
run = function (file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".rs" }, "")
end
},
html = {
run = function (file_name)
utils.write_file({ ".", file_name .. ".html" }, string.format([[
},
cpp = {
run = function(file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".cpp" }, "")
end
},
rust = {
run = function(file_name)
utils.write_file({ utils.get_project_root(), "src", file_name .. ".rs" }, "")
end
},
html = {
run = function(file_name)
utils.write_file({ ".", file_name .. ".html" }, string.format([[
<!DOCTYPE html>
<html>
<head>
@@ -235,21 +350,22 @@ public class %s {
</body>
</html>
]]))
end
}
end
}
}
M.extras = {
run = function (lang, file_name)
if lang == "c" then
extras("_H", ".h", file_name)
print("Successful creation of " .. file_name .. ".h")
end
if lang == "cpp" then
extras("_HPP", ".hpp", file_name)
print("Successful creation of " .. file_name .. ".hpp")
end
end
run = function(lang, file_name)
if lang == "c" then
extras("_H", ".h", file_name)
print("Successful creation of " .. file_name .. ".h")
elseif lang == "cpp" then
extras("_HPP", ".hpp", file_name)
print("Successful creation of " .. file_name .. ".hpp")
else
print("Extras language is not found: enter cpp or c")
end
end
}
return M
+161 -376
View File
@@ -3,402 +3,187 @@ 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
local result = {}
local handle = vim.uv.fs_scandir(path)
if not handle then return result end
while true do
local name, type = vim.uv.fs_scandir_next(handle)
if not name then break end
table.insert(result, {
name = name .. (type == "directory" and "/" or ""),
type = type,
full_path = path .. "/" .. name,
})
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
table.sort(result, function(a, b)
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 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)
local templates = require("Polydev.templates")
local width, height = math.floor(vim.o.columns * 0.40), math.floor(vim.o.lines * 0.4)
local row, col = math.floor((vim.o.lines - height) / 3), math.floor((vim.o.columns - width) / 2)
local content_row = row + 2
local content_height = height - 3
-- 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 cwd = vim.fn.getcwd()
local current_view = {}
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 content_buf = vim.api.nvim_create_buf(false, true)
local content_win = vim.api.nvim_open_win(content_buf, true, {
relative = "editor",
width = width,
height = content_height,
row = content_row,
col = col,
style = "minimal",
border = "rounded",
})
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)
local function close_all_windows()
if vim.api.nvim_win_is_valid(content_win) then
pcall(vim.api.nvim_win_close, content_win, true)
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()
local function update_screen()
local root = vim.fn.expand(project_root)
if vim.fn.isdirectory(root) == 0 then
vim.fn.mkdir(root, "p")
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()
local entries = get_entries(cwd)
if not cwd:find(root, 1, true) then
cwd = root
entries = get_entries(cwd)
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)
-- 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()
local function get_selected_entry()
local win = content_win
if not win or not vim.api.nvim_win_is_valid(win) then return end
local row = vim.api.nvim_win_get_cursor(win)[1]
return current_view[row], row
end
if entry.type == "file" then
popup:unmount()
vim.schedule(function()
vim.cmd("edit " .. vim.fn.fnameescape(entry.full_path))
end)
---@param type string
---@param callback fun(lang: string, name: string)
local function get_inputs(type, callback)
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)
popup:map("n", "<BS>", function()
local parent = vim.fn.fnamemodify(cwd, ":h")
if parent ~= cwd then
cwd = parent
refresh()
render()
end
end)
update_screen()
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
local buf = content_buf
vim.keymap.set("n", "<ESC>", function()
if vim.api.nvim_win_is_valid(content_win) then
pcall(vim.api.nvim_win_close, content_win, true)
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
popup:unmount()
end
end, 50)
end)
popup:mount()
refresh()
render()
if entry.type == "file" then
close_all_windows()
vim.cmd("edit " .. vim.fn.fnameescape(entry.full_path))
elseif entry.type == "directory" then
cwd = entry.full_path
vim.cmd("cd " .. cwd)
update_screen()
else
print("Error")
end
end, { buffer = buf })
end
return M
+78 -59
View File
@@ -2,94 +2,113 @@ local M = {}
M.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
---@param path string
---@return boolean|nil
function M.is_dir(path)
local stat = vim.loop.fs_stat(path)
return stat and stat.type == "directory"
function M.exists(path)
return (io.open(path, "r") ~= nil)
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 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
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")
return vim.fn.fnamemodify(M.get_project_root(), ":t")
end
---@param path_segments table
---@param content string
function M.write_file(path_segments, content)
local path = table.concat(path_segments, "/")
local file = assert(io.open(path, "w"), "Error creating file: " .. path)
file:write(content)
file:close()
vim.cmd("edit " .. path)
local path = table.concat(path_segments, "/")
local file = assert(io.open(path, "w"), "Error creating file: " .. path)
file:write(content)
file:close()
vim.cmd("edit " .. path)
end
---@param path string
---@param gitignore_lines table
function M.init_git(path, gitignore_lines)
vim.fn.mkdir(path, "p")
vim.fn.system({ "git", "-C", path, "init" })
vim.fn.mkdir(path, "p")
vim.fn.system({ "git", "-C", path, "init" })
if gitignore_lines and #gitignore_lines > 0 then
local gitignore_path = { path, ".gitignore" }
local contents = table.concat(gitignore_lines, "\n")
M.write_file(gitignore_path, contents)
end
if gitignore_lines and #gitignore_lines > 0 then
local contents = table.concat(gitignore_lines, "\n")
M.write_file({ path, ".gitignore" }, contents)
end
end
---@param cmd table
---@return integer, integer
---@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 M.opts.mode == "floating" then
local opts = require("Polydev.presets").getPresets(M.opts.win.anchor)
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 ui = vim.api.nvim_list_uis()[1]
local width, height, row, col
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = M.opts.border.enabled and M.opts.border.type,
})
vim.api.nvim_set_option_value("winblend", vim.o.pumblend, { win = win })
vim.api.nvim_set_option_value("winhighlight", "Normal:Pmenu,FloatBorder:Pmenu", { win = win })
vim.api.nvim_set_option_value("cursorline", true, { win = win })
vim.api.nvim_set_option_value("scrolloff", 5, { win = win })
if opts ~= nil then
width = math.max(1, math.floor(ui.width * 0.9) - opts.left - opts.right)
height = math.max(1, math.floor(ui.height * 0.9) - opts.top - opts.bottom)
row = math.floor((ui.height - height) / 2) + opts.top
col = math.floor((ui.width - width) / 2) + opts.left
end
if opts == nil then
width = math.max(1, math.floor(ui.width * 0.9))
height = math.max(1, math.floor(ui.height * 0.9))
row = math.floor((ui.height - height) / 2)
col = math.floor((ui.width - width) / 2)
end
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = M.opts.border.enabled and M.opts.border.type,
})
vim.api.nvim_set_option_value("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, "/"))
vim.api.nvim_buf_set_keymap(buf, "n", "<ESC>", "i<C-\\><C-n>:q<CR>", { noremap = true, silent = true })
return buf, win
if M.opts.win.type == "vertical" then
vim.cmd(M.opts.win.size .. " vsplit")
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
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()