Metadata-Version: 2.4
Name: pyxend
Version: 0.1.0
Summary: Python framework for building VS Code extensions
Author-email: codeflane <nta16022013@gmail.com>
License-Expression: MIT
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click
Requires-Dist: jinja2
Dynamic: license-file

# 🐍 pyxend
<p align="center">
  <img src="https://img.shields.io/pypi/v/pyxend" alt="PyPI Version">
  <img src="https://img.shields.io/pypi/l/pyxend" alt="License">
  <img src="https://img.shields.io/pypi/pyversions/pyxend" alt="Python Versions">
  <img src="https://img.shields.io/github/last-commit/codeFlane/pyxend" alt="Last Commit">
  <img src="https://img.shields.io/github/stars/codeFlane/pyxend?style=social" alt="GitHub Stars">
</p>
pyxend is a Python-based framework and CLI tool for building Visual Studio Code extensions entirely in Python. It allows developers to define extension commands using simple Python decorators and handle VS Code actions like modifying editor content, showing modals, and running terminal commands.

> ⚡️ No JavaScript required for extension logic — write VS Code extensions in pure Python.

![Preview](preview.gif)
---

## ✨ Features

- 🧠 Simple Python API for defining commands
- ⚙️ CLI tool to scaffold, sync, build, and publish extensions
- 🧩 Template-based generation of `extension.js` and `package.json`
- 🔁 Context-aware Python execution with editor data (selected text, cursor, file)
- 📦 Easy packaging using `vsce`

---

## 📦 Installation

```bash
git clone https://github.com/codeflane/pyxend
cd pyxend
pip install -e .
```
Make sure Node.js and vsce are installed:
```
npm install -g vsce
```

## 🚀 Getting Started
#### 1. Create a new extension
```bash
pyxend init "My Extension Name" myextension
```
This generates a minimal VS Code extension with:

 - extension.js
 - package.json
 - .vscodeignore

#### 2. Add logic in Python

Edit main.py:
```python
from pyxend import Extension, ModalType

ext = Extension()

@ext.command('hello')
def say_hello(ctx):
    ext.show_modal("Hello from Python!", type=ModalType.INFO)

ext.run()
```

#### 3. Sync the metadata
```bash
pyxend sync
```
This will:
 - Regenerate extension.js
 - Update package.json commands and activation events

#### 4. Build and install the extension
```bash
pyxend build
code --install-extension your-extension.vsix
```

## 🧩 Extension API
The core API is exposed via the `Extension` class.

#### `ext.command(name: str, title: Optional[str] = None)`

Decorator to register a command that can be invoked from VS Code.

##### Arguments:

* `name` – The command name (e.g., `"sayHello"`).
* `title` – Optional title to display in the Command Palette.

##### Context:

When the command is invoked, it receives a `context` dictionary with useful metadata:

```json
{
  "selected_text": "Hello",
  "language": "python",
  "cursor_pos": {"line": 3, "character": 15},
  "file_path": "D:/projects/example.py",
  "all_text": "Hello World"
}
```

##### Example:

```python
@ext.command("sayHello", title="Say Hello")
def say_hello(context):
    ext.show_modal(f"Hi! You selected: {context['selected_text']}")
```

---
#### `ext.show_modal(message: str, type: ModalType = ModalType.INFO)`
Show modal popup
##### Arguments:
 - message – The message to display.
 - type – Must be one of the ModalType values:
   - ModalType.INFO
   - ModalType.WARNING
   - ModalType.ERROR

##### Make sure to import ModalType:
```python
from pyxend import ModalType
```
##### Example:
```python
ext.show_modal("This is an error", type=ModalType.error) #Show error modal with text "This is an error"
```

---
#### `ext.replace_selected_text(text: str)`

Replace the currently selected text in the editor.

##### Arguments:

* `text` – The text that will replace the current selection.

##### Example:

```python
ext.replace_selected_text("Replaced content.") #Replace currently selected text to "Replace content."
```

---
#### `ext.insert_text(text: str)`

Insert text at the current cursor position.

##### Arguments:

* `text` – The text to insert.

##### Example:

```python
ext.insert_text("Inserted text.") #Insert text "Inserted text." after cursor position
```

---
#### `ext.open_file(path: str)`

Open a file in the editor by its path.

##### Arguments:

* `path` – Full path to the file.

##### Example:

```python
ext.open_file("D:/projects/example.py") #open "D:/projects/example.py" in editor
```

---
#### `ext.set_cursor_pos(line: int, character: int)`

Move the editor’s cursor to the specified position.

##### Arguments:

* `line` – Line number.
* `character` – Character number.

##### Example:

```python
ext.set_cursor_pos(5, 10) #move cursor to line 5, character 10
```

---
#### `ext.save_file()`

Save the current file.

##### Example:

```python
ext.save_file() #save current file
```

---
#### `ext.replace_text(text: str)`

Replace the entire content of the file.

##### Arguments:

* `text` – The new content for the whole file.

##### Example:

```python
ext.replace_text("print('Hello, World!')\n") #replace all file text to "print('Hello, World!')"
```

---
#### `ext.run_terminal_command(command: str, name: str = 'pyxend terminal')`

Execute a command in a new or existing terminal.

##### Arguments:

* `command` – The terminal command to execute.
* `name` (optional) – Name of the terminal instance. Default is "pyxend terminal"

##### Example:

```python
ext.run_terminal_command("echo 'Hello World'") #create new terminal and echo "Hello World"
```

---

## 🤝 Contributing

Pull requests welcome! Open issues or ideas on GitHub.
