refactor(command-system): standardize command execution with *args/**kwargs
- Refactor exec_with_args to use *args/**kwargs instead of tuple arguments - Add *args/**kwargs to all command execute functions for consistency - Support multiple key bindings per command in registration - Add character-based key binding support via get_char() in KeyMapper - Make execute_plugin async and use asyncio.run for plugin execution - Use MIME type from Gio content_type instead of language for ftype
This commit is contained in:
236
AGENTS.md
Normal file
236
AGENTS.md
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
# AGENTS.md - Development Guidelines for Newton
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Newton is a Python/Gtk3 desktop application (code editor) using PyGObject. The project follows specific conventions documented below.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Build, Lint, and Test Commands
|
||||||
|
|
||||||
|
### Running the Application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Activate virtual environment and run
|
||||||
|
source .venv/bin/activate
|
||||||
|
python -m src
|
||||||
|
```
|
||||||
|
|
||||||
|
### Type Checking (Pyright)
|
||||||
|
|
||||||
|
The project uses pyright for static type checking. Configuration is in `pyrightconfig.json`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run pyright (ensure venv is activated)
|
||||||
|
pyright src/
|
||||||
|
|
||||||
|
# Or via Python module
|
||||||
|
python -m pyright src/
|
||||||
|
```
|
||||||
|
|
||||||
|
**pyrightconfig.json settings:**
|
||||||
|
- `venvPath`: "."
|
||||||
|
- `venv`: ".venv"
|
||||||
|
- Reports: unused variables, unused imports, duplicate imports
|
||||||
|
|
||||||
|
### No Test Framework
|
||||||
|
|
||||||
|
**There are currently no tests in this codebase.** If tests are added:
|
||||||
|
- Use pytest as the testing framework
|
||||||
|
- Test files should be in a `tests/` directory
|
||||||
|
- Run a single test: `pytest tests/test_file.py::test_function_name`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Code Style Guidelines
|
||||||
|
|
||||||
|
### Import Organization
|
||||||
|
|
||||||
|
Imports must be organized with blank lines between groups (in this exact order):
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Python imports
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
import gi
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
|
||||||
|
from gi.repository import Gtk
|
||||||
|
from gi.repository import GLib
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from libs.dto.states import SourceViewStates
|
||||||
|
from .mixins.source_view_dnd_mixin import SourceViewDnDMixin
|
||||||
|
```
|
||||||
|
|
||||||
|
### Type Hints
|
||||||
|
|
||||||
|
- Use type hints for all function parameters and return types
|
||||||
|
- Use Python's built-in types (`list[str]`, `dict[str, int]`) not typing module aliases
|
||||||
|
- Example: `def message_to(self, name: str, event: BaseEvent):`
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
|
||||||
|
| Element | Convention | Example |
|
||||||
|
|---------|------------|---------|
|
||||||
|
| Classes | PascalCase | `ControllerBase`, `SourceView` |
|
||||||
|
| Methods/Variables | snake_case | `set_controller_context`, `_cut_buffer` |
|
||||||
|
| Private methods | Leading underscore | `_setup_styles`, `_subscribe_to_events` |
|
||||||
|
| Constants | UPPER_SNAKE_CASE | `LOG_LEVEL`, `DEFAULT_ZOOM` |
|
||||||
|
| Exception classes | PascalCase ending in Exception | `ControllerBaseException` |
|
||||||
|
|
||||||
|
### Class Structure
|
||||||
|
|
||||||
|
```python
|
||||||
|
class MyClass(Singleton, EmitDispatcher):
|
||||||
|
def __init__(self):
|
||||||
|
super(MyClass, self).__init__()
|
||||||
|
|
||||||
|
self.controller_context: ControllerContext = None
|
||||||
|
self._private_var = None
|
||||||
|
|
||||||
|
def public_method(self, param: str) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
def _private_method(self) -> None:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Placeholder Methods
|
||||||
|
|
||||||
|
Use ellipsis `...` for unimplemented methods or abstract-like methods:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def _subscribe_to_events(self):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dataclasses for DTOs/Events
|
||||||
|
|
||||||
|
Use `@dataclass` for data transfer objects and events:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TextInsertedEvent(CodeEvent):
|
||||||
|
location: Gtk.TextIter = None
|
||||||
|
text: str = ""
|
||||||
|
length: int = 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
- Custom exceptions should end with `Exception`
|
||||||
|
- Use `raise ValueError("message")` for validation errors
|
||||||
|
- Let exceptions propagate for unexpected errors
|
||||||
|
|
||||||
|
### Singleton Pattern
|
||||||
|
|
||||||
|
Classes requiring singleton behavior should inherit from `Singleton`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from libs.singleton import Singleton
|
||||||
|
|
||||||
|
class MySingleton(Singleton):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### GTK/Widget Conventions
|
||||||
|
|
||||||
|
- Call `_setup_styles()`, `_setup_signals()`, `_subscribe_to_events()`, `_load_widgets()` in `__init__`
|
||||||
|
- Use `self.connect("signal-name", self._handler)` for GTK signals
|
||||||
|
- Private GTK attributes use underscore prefix: `self._cut_temp_timeout_id`
|
||||||
|
|
||||||
|
### Code Formatting
|
||||||
|
|
||||||
|
- Use spaces around operators: `x = value`, not `x=value`
|
||||||
|
- Align assignments with spaces for related variables:
|
||||||
|
```python
|
||||||
|
self.state = state
|
||||||
|
self._cut_temp_timeout_id = None
|
||||||
|
```
|
||||||
|
- Maximum line length: Let pyright/editor handle warnings (typically 80-120 chars)
|
||||||
|
|
||||||
|
### No Comments
|
||||||
|
|
||||||
|
DO NOT add comments to code unless explicitly required. Write self-documenting code.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
Newton/
|
||||||
|
├── src/
|
||||||
|
│ ├── app.py # Main application entry
|
||||||
|
│ ├── __main__.py # Module entry point
|
||||||
|
│ ├── __builtins__.py # Built-in definitions
|
||||||
|
│ ├── core/ # Core UI components
|
||||||
|
│ │ ├── containers/ # Layout containers
|
||||||
|
│ │ ├── controllers/ # Controllers
|
||||||
|
│ │ └── widgets/ # GTK widgets
|
||||||
|
│ ├── libs/ # Core libraries
|
||||||
|
│ │ ├── controllers/ # Controller infrastructure
|
||||||
|
│ │ ├── db/ # Database (SQLModel)
|
||||||
|
│ │ ├── dto/ # Data transfer objects
|
||||||
|
│ │ ├── mixins/ # Mixin classes
|
||||||
|
│ │ └── settings/ # Settings management
|
||||||
|
│ └── plugins/ # Plugin system
|
||||||
|
├── plugins/ # Plugin implementations
|
||||||
|
├── user_config/ # User configuration files
|
||||||
|
├── requirements.txt # Python dependencies
|
||||||
|
└── pyrightconfig.json # Pyright configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Libraries Used
|
||||||
|
|
||||||
|
- **PyGObject** (GTK3) - GUI framework
|
||||||
|
- **sqlmodel** - Database (SQLAlchemy + Pydantic)
|
||||||
|
- **setproctitle** - Process title management
|
||||||
|
- **pyxdg** - XDG desktop file parsing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Creating a New Controller
|
||||||
|
|
||||||
|
```python
|
||||||
|
from libs.controllers.controller_base import ControllerBase
|
||||||
|
from libs.controllers.controller_context import ControllerContext
|
||||||
|
|
||||||
|
class MyController(ControllerBase):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.controller_context = None
|
||||||
|
|
||||||
|
def _controller_message(self, event: BaseEvent):
|
||||||
|
# Handle events
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
### Creating a New Event/DTO
|
||||||
|
|
||||||
|
```python
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from libs.dto.code.code_event import CodeEvent
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class MyEvent(CodeEvent):
|
||||||
|
field1: str = ""
|
||||||
|
field2: int = 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connecting to Events
|
||||||
|
|
||||||
|
```python
|
||||||
|
from libs.event_system import EventSystem
|
||||||
|
|
||||||
|
event_system = EventSystem()
|
||||||
|
event_system.subscribe("event_name", self.my_handler)
|
||||||
|
```
|
||||||
3
plugins/code/autopairs/__init__.py
Normal file
3
plugins/code/autopairs/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
"""
|
||||||
|
Plugin Module
|
||||||
|
"""
|
||||||
3
plugins/code/autopairs/__main__.py
Normal file
3
plugins/code/autopairs/__main__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
"""
|
||||||
|
Plugin Package
|
||||||
|
"""
|
||||||
97
plugins/code/autopairs/autopairs.py
Normal file
97
plugins/code/autopairs/autopairs.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
# Python imports
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Autopairs:
|
||||||
|
def __init__(self):
|
||||||
|
...
|
||||||
|
|
||||||
|
def handle_word_wrap(self, buffer, char_str: str):
|
||||||
|
wrap_block = self.get_wrap_block(char_str)
|
||||||
|
if not wrap_block: return
|
||||||
|
|
||||||
|
selection = buffer.get_selection_bounds()
|
||||||
|
if not selection:
|
||||||
|
self.insert_pair(buffer, char_str, wrap_block)
|
||||||
|
return True
|
||||||
|
|
||||||
|
self.wrap_selection(buffer, char_str, wrap_block, selection)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def insert_pair(
|
||||||
|
self, buffer, char_str: str, wrap_block: tuple
|
||||||
|
):
|
||||||
|
buffer.begin_user_action()
|
||||||
|
|
||||||
|
left_block, right_block = wrap_block
|
||||||
|
insert_mark = buffer.get_insert()
|
||||||
|
|
||||||
|
insert_itr = buffer.get_iter_at_mark(insert_mark)
|
||||||
|
buffer.insert(insert_itr, f"{left_block}{right_block}")
|
||||||
|
insert_itr = buffer.get_iter_at_mark( insert_mark )
|
||||||
|
insert_itr.backward_char()
|
||||||
|
|
||||||
|
buffer.place_cursor(insert_itr)
|
||||||
|
|
||||||
|
buffer.end_user_action()
|
||||||
|
|
||||||
|
def wrap_selection(
|
||||||
|
self, buffer, char_str: str, wrap_block: tuple, selection
|
||||||
|
):
|
||||||
|
left_block, \
|
||||||
|
right_block = wrap_block
|
||||||
|
start_itr, \
|
||||||
|
end_itr = selection
|
||||||
|
data = buffer.get_text(
|
||||||
|
start_itr, end_itr, include_hidden_chars = False
|
||||||
|
)
|
||||||
|
start_mark = buffer.create_mark("startclose", start_itr, False)
|
||||||
|
end_mark = buffer.create_mark("endclose", end_itr, True)
|
||||||
|
|
||||||
|
buffer.begin_user_action()
|
||||||
|
|
||||||
|
buffer.insert(start_itr, left_block)
|
||||||
|
end_itr = buffer.get_iter_at_mark(end_mark)
|
||||||
|
buffer.insert(end_itr, right_block)
|
||||||
|
|
||||||
|
start = buffer.get_iter_at_mark(start_mark)
|
||||||
|
end = buffer.get_iter_at_mark(end_mark)
|
||||||
|
|
||||||
|
buffer.select_range(start, end)
|
||||||
|
buffer.delete_mark_by_name("startclose")
|
||||||
|
buffer.delete_mark_by_name("endclose")
|
||||||
|
|
||||||
|
buffer.end_user_action()
|
||||||
|
|
||||||
|
def get_wrap_block(self, char_str) -> tuple:
|
||||||
|
left_block = ""
|
||||||
|
right_block = ""
|
||||||
|
|
||||||
|
match char_str:
|
||||||
|
case "(" | ")":
|
||||||
|
left_block = "("
|
||||||
|
right_block = ")"
|
||||||
|
case "[" | "]":
|
||||||
|
left_block = "["
|
||||||
|
right_block = "]"
|
||||||
|
case "{" | "}":
|
||||||
|
left_block = "{"
|
||||||
|
right_block = "}"
|
||||||
|
case '"':
|
||||||
|
left_block = '"'
|
||||||
|
right_block = '"'
|
||||||
|
case "'":
|
||||||
|
left_block = "'"
|
||||||
|
right_block = "'"
|
||||||
|
case "`":
|
||||||
|
left_block = "`"
|
||||||
|
right_block = "`"
|
||||||
|
case _:
|
||||||
|
return ()
|
||||||
|
|
||||||
|
return left_block, right_block
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Autopairs",
|
"name": "Autopairs",
|
||||||
"author": "ITDominator",
|
"author": "ITDominator",
|
||||||
"credit": "Hamad Al Marri",
|
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"support": "",
|
"support": "",
|
||||||
"requests": {
|
"requests": {}
|
||||||
"pass_events": true
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
53
plugins/code/autopairs/plugin.py
Normal file
53
plugins/code/autopairs/plugin.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# Python imports
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
|
|
||||||
|
from plugins.plugin_types import PluginCode
|
||||||
|
|
||||||
|
from .autopairs import Autopairs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
autopairs = Autopairs()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Plugin(PluginCode):
|
||||||
|
def __init__(self):
|
||||||
|
super(Plugin, self).__init__()
|
||||||
|
|
||||||
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
|
...
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
event = Event_Factory.create_event("register_command",
|
||||||
|
command_name = "autopairs",
|
||||||
|
command = Handler,
|
||||||
|
binding_mode = "held",
|
||||||
|
binding = [
|
||||||
|
"'", "`", "[", "]",
|
||||||
|
'<Shift>"',
|
||||||
|
'<Shift>(',
|
||||||
|
'<Shift>)',
|
||||||
|
'<Shift>{',
|
||||||
|
'<Shift>}'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.message_to("source_views", event)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class Handler:
|
||||||
|
@staticmethod
|
||||||
|
def execute(
|
||||||
|
view: any,
|
||||||
|
char_str: str
|
||||||
|
):
|
||||||
|
logger.debug("Command: Autopairs")
|
||||||
|
autopairs.handle_word_wrap(view.get_buffer(), char_str)
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Module
|
|
||||||
"""
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Package
|
|
||||||
"""
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
import os
|
|
||||||
import threading
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from plugins.plugin_base import PluginBase
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# NOTE: Threads WILL NOT die with parent's destruction.
|
|
||||||
def threaded(fn):
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start()
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
# NOTE: Threads WILL die with parent's destruction.
|
|
||||||
def daemon_threaded(fn):
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin(PluginBase):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
self.name = "Autopairs" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus
|
|
||||||
# where self.name should not be needed for message comms
|
|
||||||
|
|
||||||
self.chars = {
|
|
||||||
"quotedbl": "\"",
|
|
||||||
"apostrophe": "'",
|
|
||||||
"parenleft": "(",
|
|
||||||
"bracketleft": "[",
|
|
||||||
"braceleft": "{",
|
|
||||||
"less": "<",
|
|
||||||
"grave": "`",
|
|
||||||
}
|
|
||||||
|
|
||||||
self.close = {
|
|
||||||
"\"": "\"",
|
|
||||||
"'": "'",
|
|
||||||
"(": ")",
|
|
||||||
"[": "]",
|
|
||||||
"{": "}",
|
|
||||||
"<": ">",
|
|
||||||
"`": "`",
|
|
||||||
}
|
|
||||||
|
|
||||||
def generate_reference_ui_element(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def subscribe_to_events(self):
|
|
||||||
self._event_system.subscribe("set_active_src_view", self._set_active_src_view)
|
|
||||||
self._event_system.subscribe("autopairs", self._autopairs)
|
|
||||||
|
|
||||||
def _set_active_src_view(self, source_view):
|
|
||||||
self._active_src_view = source_view
|
|
||||||
self._buffer = self._active_src_view.get_buffer()
|
|
||||||
self._tag_table = self._buffer.get_tag_table()
|
|
||||||
|
|
||||||
def _autopairs(self, keyval_name, ctrl, alt, shift):
|
|
||||||
if keyval_name in self.chars:
|
|
||||||
return self.text_insert(self._buffer, keyval_name)
|
|
||||||
|
|
||||||
# NOTE: All of below to EOF, lovingly taken from Hamad Al Marri's Gamma
|
|
||||||
# text editor. I did do some cleanup of comments but otherwise pretty
|
|
||||||
# much the same code just fitted to my plugin architecture.
|
|
||||||
# Link: https://gitlab.com/hamadmarri/gamma-text-editor
|
|
||||||
def text_insert(self, buffer, text):
|
|
||||||
selection = buffer.get_selection_bounds()
|
|
||||||
if selection == ():
|
|
||||||
return self.add_close(buffer, text, )
|
|
||||||
else:
|
|
||||||
return self.add_enclose(buffer, text, selection)
|
|
||||||
|
|
||||||
def add_close(self, buffer, text):
|
|
||||||
text = self.chars[text]
|
|
||||||
text += self.close[text]
|
|
||||||
|
|
||||||
position = buffer.get_iter_at_mark( buffer.get_insert() )
|
|
||||||
|
|
||||||
c = position.get_char()
|
|
||||||
if not c in (" ", "", ";", ":", "\t", ",", ".", "\n", "\r") \
|
|
||||||
and not c in list(self.close.values()):
|
|
||||||
return False
|
|
||||||
|
|
||||||
buffer.insert(position, text)
|
|
||||||
|
|
||||||
position = buffer.get_iter_at_mark(buffer.get_insert())
|
|
||||||
position.backward_char()
|
|
||||||
buffer.place_cursor(position)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def add_enclose(self, buffer, text, selection):
|
|
||||||
(start, end) = selection
|
|
||||||
selected = buffer.get_text(start, end, False)
|
|
||||||
if len(selected) <= 3 and selected in ("<", ">", ">>>"
|
|
||||||
"<<", ">>",
|
|
||||||
"\"", "'", "`",
|
|
||||||
"(", ")",
|
|
||||||
"[", "]",
|
|
||||||
"{", "}",
|
|
||||||
"=", "==",
|
|
||||||
"!=", "==="):
|
|
||||||
return False
|
|
||||||
|
|
||||||
start_mark = buffer.create_mark("startclose", start, False)
|
|
||||||
end_mark = buffer.create_mark("endclose", end, False)
|
|
||||||
|
|
||||||
buffer.begin_user_action()
|
|
||||||
|
|
||||||
t = self.chars[text]
|
|
||||||
buffer.insert(start, t)
|
|
||||||
end = buffer.get_iter_at_mark(end_mark)
|
|
||||||
t = self.close[t]
|
|
||||||
buffer.insert(end, t)
|
|
||||||
|
|
||||||
start = buffer.get_iter_at_mark(start_mark)
|
|
||||||
end = buffer.get_iter_at_mark(end_mark)
|
|
||||||
end.backward_char()
|
|
||||||
buffer.select_range(start, end)
|
|
||||||
|
|
||||||
buffer.end_user_action()
|
|
||||||
|
|
||||||
return True
|
|
||||||
@@ -9,7 +9,6 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
def set_language_and_style(view, file):
|
def set_language_and_style(view, file):
|
||||||
language = view.language_manager.guess_language(file.fname, None)
|
language = view.language_manager.guess_language(file.fname, None)
|
||||||
file.ftype = "buffer" if not language else language
|
|
||||||
file.buffer.set_language(language)
|
file.buffer.set_language(language)
|
||||||
file.buffer.set_style_scheme(view.syntax_theme)
|
file.buffer.set_style_scheme(view.syntax_theme)
|
||||||
|
|
||||||
|
|||||||
@@ -26,16 +26,13 @@ class CommandSystem:
|
|||||||
method = getattr(commands, command)
|
method = getattr(commands, command)
|
||||||
|
|
||||||
args, kwargs = self.data
|
args, kwargs = self.data
|
||||||
if kwargs:
|
return method.execute(*args, **kwargs)
|
||||||
return method.execute(*args, kwargs)
|
|
||||||
else:
|
|
||||||
return method.execute(*args)
|
|
||||||
|
|
||||||
def exec_with_args(self, command: str, args: list) -> any:
|
def exec_with_args(self, command: str, *args, **kwargs) -> any:
|
||||||
if not hasattr(commands, command): return
|
if not hasattr(commands, command): return
|
||||||
|
|
||||||
method = getattr(commands, command)
|
method = getattr(commands, command)
|
||||||
return method.execute(*args)
|
return method.execute(*args, **kwargs)
|
||||||
|
|
||||||
def add_command(self, command_name: str, command: callable):
|
def add_command(self, command_name: str, command: callable):
|
||||||
setattr(commands, command_name, command)
|
setattr(commands, command_name, command)
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Buffer Redo")
|
logger.debug("Command: Buffer Redo")
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Buffer Undo")
|
logger.debug("Command: Buffer Undo")
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from ..command_helpers import update_info_bar_if_focused
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Close File")
|
logger.debug("Command: Close File")
|
||||||
view.command.remove_file(view)
|
view.command.remove_file(view)
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Cut to Temp Buffer")
|
logger.debug("Command: Cut to Temp Buffer")
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ from ..command_helpers import update_info_bar_if_focused
|
|||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View,
|
view: GtkSource.View,
|
||||||
uri: str
|
uri: str,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: DnD Load File To Buffer")
|
logger.debug("Command: DnD Load File To Buffer")
|
||||||
file = view.command.new_file(view)
|
file = view.command.new_file(view)
|
||||||
@@ -23,7 +25,7 @@ def execute(
|
|||||||
gfile = Gio.File.new_for_uri(uri)
|
gfile = Gio.File.new_for_uri(uri)
|
||||||
view.command.exec_with_args(
|
view.command.exec_with_args(
|
||||||
"load_file",
|
"load_file",
|
||||||
(view, gfile, file)
|
view, gfile, file
|
||||||
)
|
)
|
||||||
|
|
||||||
view.set_buffer(file.buffer)
|
view.set_buffer(file.buffer)
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ from gi.repository import Gio
|
|||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View,
|
view: GtkSource.View,
|
||||||
uris: list = []
|
uris: list = [],
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: DnD Load Files")
|
logger.debug("Command: DnD Load Files")
|
||||||
for uri in uris:
|
for uri in uris:
|
||||||
@@ -23,4 +25,4 @@ def execute(
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
gfile = Gio.File.new_for_path(uri)
|
gfile = Gio.File.new_for_path(uri)
|
||||||
|
|
||||||
view.command.exec_with_args("load_file", (view, gfile))
|
view.command.exec_with_args("load_file", view, gfile)
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Duplicate Line")
|
logger.debug("Command: Duplicate Line")
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Focus Left Sibling")
|
logger.debug("Command: Focus Left Sibling")
|
||||||
if not view.sibling_left: return
|
if not view.sibling_left: return
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Focus Right Sibling")
|
logger.debug("Command: Focus Right Sibling")
|
||||||
if not view.sibling_right: return
|
if not view.sibling_right: return
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Get Current File")
|
logger.debug("Command: Get Current File")
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Get File Type")
|
logger.debug("Command: Get File Type")
|
||||||
file = view.command.get_file(view)
|
file = view.command.get_file(view)
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Get Text")
|
logger.debug("Command: Get Text")
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Go-To")
|
logger.debug("Command: Go-To")
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Has Focus")
|
logger.debug("Command: Has Focus")
|
||||||
ctx = view.get_parent().get_style_context()
|
ctx = view.get_parent().get_style_context()
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Line Down")
|
logger.debug("Command: Line Down")
|
||||||
view.emit("move-lines", True)
|
view.emit("move-lines", True)
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Line Up")
|
logger.debug("Command: Line Up")
|
||||||
view.emit("move-lines", False)
|
view.emit("move-lines", False)
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ def execute(
|
|||||||
view: GtkSource.View,
|
view: GtkSource.View,
|
||||||
gfile: Gio.File,
|
gfile: Gio.File,
|
||||||
file: SourceFile = None,
|
file: SourceFile = None,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Load File")
|
logger.debug("Command: Load File")
|
||||||
if not file:
|
if not file:
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ from gi.repository import Gio
|
|||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View,
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Load Start File(s)")
|
logger.debug("Command: Load Start File(s)")
|
||||||
|
|
||||||
@@ -28,7 +30,7 @@ def execute(
|
|||||||
|
|
||||||
view.command.exec_with_args(
|
view.command.exec_with_args(
|
||||||
"load_file",
|
"load_file",
|
||||||
(view, gfile, file)
|
view, gfile, file
|
||||||
)
|
)
|
||||||
|
|
||||||
if not starting_files: return
|
if not starting_files: return
|
||||||
@@ -37,4 +39,4 @@ def execute(
|
|||||||
file = file.replace("FILE|", "")
|
file = file.replace("FILE|", "")
|
||||||
gfile = Gio.File.new_for_path(file)
|
gfile = Gio.File.new_for_path(file)
|
||||||
|
|
||||||
view.command.exec_with_args("load_file", (view, gfile))
|
view.command.exec_with_args("load_file", view, gfile)
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Move To Left Sibling")
|
logger.debug("Command: Move To Left Sibling")
|
||||||
if not view.sibling_left: return
|
if not view.sibling_left: return
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Move To Right Sibling")
|
logger.debug("Command: Move To Right Sibling")
|
||||||
if not view.sibling_right: return
|
if not view.sibling_right: return
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ from ..command_helpers import set_language_and_style, update_info_bar_if_focused
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: New File")
|
logger.debug("Command: New File")
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from ..command_helpers import update_info_bar_if_focused
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Open File(s)")
|
logger.debug("Command: Open File(s)")
|
||||||
gfiles = event_system.emit_and_await("open-files")
|
gfiles = event_system.emit_and_await("open-files")
|
||||||
@@ -22,9 +24,9 @@ def execute(
|
|||||||
file = view.command.get_file(view)
|
file = view.command.get_file(view)
|
||||||
if file.ftype == "buffer":
|
if file.ftype == "buffer":
|
||||||
gfile = gfiles.pop()
|
gfile = gfiles.pop()
|
||||||
view.command.exec_with_args("load_file", (view, gfile, file))
|
view.command.exec_with_args("load_file", view, gfile, file)
|
||||||
view.set_buffer(file.buffer)
|
view.set_buffer(file.buffer)
|
||||||
update_info_bar_if_focused(view.command, view)
|
update_info_bar_if_focused(view.command, view)
|
||||||
|
|
||||||
for i, gfile in enumerate(gfiles):
|
for i, gfile in enumerate(gfiles):
|
||||||
view.command.exec_with_args("load_file", (view, gfile))
|
view.command.exec_with_args("load_file", view, gfile)
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Paste Temp Buffer")
|
logger.debug("Command: Paste Temp Buffer")
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from ..command_helpers import set_language_and_style
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Save File")
|
logger.debug("Command: Save File")
|
||||||
file = view.command.get_file(view)
|
file = view.command.get_file(view)
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from ..command_helpers import set_language_and_style, update_info_bar_if_focused
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.info("Command: Save File As")
|
logger.info("Command: Save File As")
|
||||||
file = view.command.get_file(view)
|
file = view.command.get_file(view)
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ from ..command_helpers import update_info_bar_if_focused
|
|||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View,
|
view: GtkSource.View,
|
||||||
file: SourceFile
|
file: SourceFile,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Set Buffer")
|
logger.debug("Command: Set Buffer")
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View,
|
view: GtkSource.View,
|
||||||
language: str
|
language: str,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Set Buffer Language")
|
logger.debug("Command: Set Buffer Language")
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View,
|
view: GtkSource.View,
|
||||||
style: str
|
style: str,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Set Buffer Style")
|
logger.debug("Command: Set Buffer Style")
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Set Focus Border")
|
logger.debug("Command: Set Focus Border")
|
||||||
ctx = view.get_parent().get_style_context()
|
ctx = view.get_parent().get_style_context()
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View,
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Set MiniView")
|
logger.debug("Command: Set MiniView")
|
||||||
event_system.emit("set-mini-view", (view,))
|
event_system.emit("set-mini-view", (view,))
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Show Completion")
|
logger.debug("Command: Show Completion")
|
||||||
completer = view.get_completion()
|
completer = view.get_completion()
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ from gi.repository import GtkSource
|
|||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View,
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Update Info Bar")
|
logger.debug("Command: Update Info Bar")
|
||||||
file = view.command.get_file(view)
|
file = view.command.get_file(view)
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from gi.repository import Pango
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Zoom In")
|
logger.debug("Command: Zoom In")
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from gi.repository import Pango
|
|||||||
|
|
||||||
|
|
||||||
def execute(
|
def execute(
|
||||||
view: GtkSource.View = None
|
view: GtkSource.View,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
logger.debug("Command: Zoom Out")
|
logger.debug("Command: Zoom Out")
|
||||||
|
|
||||||
|
|||||||
@@ -40,12 +40,16 @@ class SourceViewsController(ControllerBase, list):
|
|||||||
self.signal_mapper.insert_text(event.file, event.text)
|
self.signal_mapper.insert_text(event.file, event.text)
|
||||||
|
|
||||||
def _register_command(self, event: Code_Event_Types.RegisterCommandEvent):
|
def _register_command(self, event: Code_Event_Types.RegisterCommandEvent):
|
||||||
self.state_manager.key_mapper.map_command(
|
if not isinstance(event.binding, list):
|
||||||
event.command_name,
|
event.binding = [ event.binding ]
|
||||||
{
|
|
||||||
f"{event.binding_mode}": event.binding
|
for binding in event.binding:
|
||||||
}
|
self.state_manager.key_mapper.map_command(
|
||||||
)
|
event.command_name,
|
||||||
|
{
|
||||||
|
f"{event.binding_mode}": binding
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
for view in self:
|
for view in self:
|
||||||
view.command.add_command(
|
view.command.add_command(
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ class SourceViewsInsertState:
|
|||||||
event = Event_Factory.create_event("focused_view", view = source_view)
|
event = Event_Factory.create_event("focused_view", view = source_view)
|
||||||
emit(event)
|
emit(event)
|
||||||
|
|
||||||
def insert_text(self, file, text):
|
def insert_text(self, file, text: str):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def move_cursor(self, source_view, step, count, extend_selection, emit):
|
def move_cursor(self, source_view, step, count, extend_selection, emit):
|
||||||
@@ -51,21 +52,23 @@ class SourceViewsInsertState:
|
|||||||
def key_press_event(self, source_view, eve, key_mapper):
|
def key_press_event(self, source_view, eve, key_mapper):
|
||||||
command = key_mapper._key_press_event(eve)
|
command = key_mapper._key_press_event(eve)
|
||||||
is_future = key_mapper._key_release_event(eve)
|
is_future = key_mapper._key_release_event(eve)
|
||||||
|
char_str = key_mapper.get_char(eve)
|
||||||
|
|
||||||
if is_future: return True
|
if is_future: return True
|
||||||
if not command: return False
|
if not command: return False
|
||||||
|
|
||||||
source_view.command.exec(command)
|
source_view.command.exec_with_args(command, source_view, char_str)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def key_release_event(self, source_view, eve, key_mapper):
|
def key_release_event(self, source_view, eve, key_mapper):
|
||||||
command = key_mapper._key_release_event(eve)
|
command = key_mapper._key_release_event(eve)
|
||||||
is_past = key_mapper._key_press_event(eve)
|
is_past = key_mapper._key_press_event(eve)
|
||||||
|
char_str = key_mapper.get_char(eve)
|
||||||
|
|
||||||
if is_past: return True
|
if is_past: return True
|
||||||
if not command: return False
|
if not command: return False
|
||||||
|
|
||||||
source_view.command.exec(command)
|
source_view.command.exec_with_args(command, source_view, char_str)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -96,19 +96,28 @@ class KeyMapper:
|
|||||||
getattr(self.states[state], press_state)[keyname] = command
|
getattr(self.states[state], press_state)[keyname] = command
|
||||||
|
|
||||||
def _key_press_event(self, eve):
|
def _key_press_event(self, eve):
|
||||||
keyname = Gdk.keyval_name(eve.keyval).lower()
|
keyname = self.get_keyname(eve)
|
||||||
|
char_str = self.get_char(eve)
|
||||||
|
|
||||||
self._set_key_state(eve)
|
self._set_key_state(eve)
|
||||||
if keyname in self.states[self.state].held:
|
if keyname in self.states[self.state].held:
|
||||||
return self.states[self.state].held[keyname]
|
return self.states[self.state].held[keyname]
|
||||||
|
|
||||||
|
if char_str in self.states[self.state].held:
|
||||||
|
return self.states[self.state].held[char_str]
|
||||||
|
|
||||||
|
|
||||||
def _key_release_event(self, eve):
|
def _key_release_event(self, eve):
|
||||||
keyname = Gdk.keyval_name(eve.keyval).lower()
|
keyname = self.get_keyname(eve)
|
||||||
|
char_str = self.get_char(eve)
|
||||||
|
|
||||||
self._set_key_state(eve)
|
self._set_key_state(eve)
|
||||||
if keyname in self.states[self.state].released:
|
if keyname in self.states[self.state].released:
|
||||||
return self.states[self.state].released[keyname]
|
return self.states[self.state].released[keyname]
|
||||||
|
|
||||||
|
if char_str in self.states[self.state].released:
|
||||||
|
return self.states[self.state].released[char_str]
|
||||||
|
|
||||||
def _set_key_state(self, eve):
|
def _set_key_state(self, eve):
|
||||||
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
|
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
|
||||||
is_control = modifiers & Gdk.ModifierType.CONTROL_MASK
|
is_control = modifiers & Gdk.ModifierType.CONTROL_MASK
|
||||||
@@ -137,3 +146,9 @@ class KeyMapper:
|
|||||||
|
|
||||||
def get_raw_keyname(self, eve):
|
def get_raw_keyname(self, eve):
|
||||||
return Gdk.keyval_name(eve.keyval)
|
return Gdk.keyval_name(eve.keyval)
|
||||||
|
|
||||||
|
def get_keyname(self, eve):
|
||||||
|
return Gdk.keyval_name(eve.keyval).lower()
|
||||||
|
|
||||||
|
def get_char(self, eve):
|
||||||
|
return chr( Gdk.keyval_to_unicode(eve.keyval) )
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class SourceViewDnDMixin:
|
|||||||
|
|
||||||
def _on_uri_data_received(self, uris: []):
|
def _on_uri_data_received(self, uris: []):
|
||||||
uri = uris.pop(0)
|
uri = uris.pop(0)
|
||||||
self.command.exec_with_args("dnd_load_file_to_buffer", (self, uri))
|
self.command.exec_with_args("dnd_load_file_to_buffer", self, uri)
|
||||||
|
|
||||||
if not uris: return
|
if not uris: return
|
||||||
|
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ class SourceFile(GtkSource.File):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Note: 'idle_add' needed b/c markers don't get thir positions
|
# Note: 'idle_add' needed b/c markers don't get thir positions
|
||||||
# updated relative to the initial insert.
|
# updated relative to the initial insert.
|
||||||
# If not used, seg faults galor during multi insert.
|
# If not used, seg faults galor during multi insert.
|
||||||
GLib.idle_add(self.emit, event)
|
GLib.idle_add(self.emit, event)
|
||||||
|
|
||||||
def _mark_set(
|
def _mark_set(
|
||||||
@@ -136,7 +136,6 @@ class SourceFile(GtkSource.File):
|
|||||||
|
|
||||||
if self.was_deleted:
|
if self.was_deleted:
|
||||||
self.was_deleted = False
|
self.was_deleted = False
|
||||||
# self.set_path(gfile)
|
|
||||||
self.set_location( None )
|
self.set_location( None )
|
||||||
self.set_location( gfile )
|
self.set_location( gfile )
|
||||||
|
|
||||||
@@ -148,6 +147,11 @@ class SourceFile(GtkSource.File):
|
|||||||
|
|
||||||
self.set_path(gfile)
|
self.set_path(gfile)
|
||||||
text = gfile.load_bytes()[0].get_data().decode("UTF-8")
|
text = gfile.load_bytes()[0].get_data().decode("UTF-8")
|
||||||
|
info = gfile.query_info('standard::content-type', Gio.FileQueryInfoFlags.NONE, None)
|
||||||
|
content_type = info.get_content_type()
|
||||||
|
self.ftype = Gio.content_type_get_mime_type(content_type)
|
||||||
|
logger.debug(f"File content type: {self.ftype}")
|
||||||
|
|
||||||
undo_manager = self.buffer.get_undo_manager()
|
undo_manager = self.buffer.get_undo_manager()
|
||||||
|
|
||||||
def move_insert_to_start():
|
def move_insert_to_start():
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ class TabWidget(Gtk.Box):
|
|||||||
|
|
||||||
self.set_orientation(0)
|
self.set_orientation(0)
|
||||||
self.set_hexpand(False)
|
self.set_hexpand(False)
|
||||||
|
self.set_vexpand(False)
|
||||||
|
self.set_size_request(-1, 12)
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ class ControllerManager(Singleton, dict):
|
|||||||
raise ControllerManagerException("Must pass in a 'name' and 'controller'...")
|
raise ControllerManagerException("Must pass in a 'name' and 'controller'...")
|
||||||
|
|
||||||
if name in self.keys():
|
if name in self.keys():
|
||||||
raise ControllerManagerException(f"Can't bind controller to registered name of '{name}'...")
|
raise ControllerManagerException(
|
||||||
|
f"Can't bind controller to existing registered name of '{name}'..."
|
||||||
|
)
|
||||||
|
|
||||||
controller.set_controller_context( self._crete_controller_context() )
|
controller.set_controller_context( self._crete_controller_context() )
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from ..base_event import BaseEvent
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class RegisterCommandEvent(BaseEvent):
|
class RegisterCommandEvent(BaseEvent):
|
||||||
command_name: str = ""
|
command_name: str = ""
|
||||||
command: callable = None
|
command: callable = None
|
||||||
binding_mode: str = ""
|
binding_mode: str = ""
|
||||||
binding: str = ""
|
binding: str or list = ""
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import importlib
|
import importlib
|
||||||
import traceback
|
import traceback
|
||||||
|
import asyncio
|
||||||
from os.path import join
|
from os.path import join
|
||||||
from os.path import isdir
|
from os.path import isdir
|
||||||
|
|
||||||
@@ -75,9 +76,14 @@ class PluginsController(ControllerBase, PluginsControllerMixin, PluginReloadMixi
|
|||||||
module = self._load_plugin_module(path, folder, target)
|
module = self._load_plugin_module(path, folder, target)
|
||||||
|
|
||||||
if is_pre_launch:
|
if is_pre_launch:
|
||||||
self.execute_plugin(module, manifest_meta)
|
asyncio.run(
|
||||||
|
self.execute_plugin(module, manifest_meta)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
GLib.idle_add(self.execute_plugin, module, manifest_meta)
|
GLib.idle_add(
|
||||||
|
asyncio.run,
|
||||||
|
self.execute_plugin(module, manifest_meta)
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(f"Malformed Plugin: Not loading -->: '{folder}' !")
|
logger.info(f"Malformed Plugin: Not loading -->: '{folder}' !")
|
||||||
logger.debug(f"Trace: {traceback.print_exc()}")
|
logger.debug(f"Trace: {traceback.print_exc()}")
|
||||||
@@ -119,7 +125,7 @@ class PluginsController(ControllerBase, PluginsControllerMixin, PluginReloadMixi
|
|||||||
manifest_metas: list = self._manifest_manager.get_post_launch_plugins()
|
manifest_metas: list = self._manifest_manager.get_post_launch_plugins()
|
||||||
self._load_plugins(manifest_metas)
|
self._load_plugins(manifest_metas)
|
||||||
|
|
||||||
def execute_plugin(self, module: type, manifest_meta: ManifestMeta):
|
async def execute_plugin(self, module: type, manifest_meta: ManifestMeta):
|
||||||
plugin = module.Plugin()
|
plugin = module.Plugin()
|
||||||
plugin.plugin_context: PluginContext = self.create_plugin_context()
|
plugin.plugin_context: PluginContext = self.create_plugin_context()
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ scrollbar slider:active {
|
|||||||
.tab-label {
|
.tab-label {
|
||||||
margin-left: 2em;
|
margin-left: 2em;
|
||||||
margin-right: 2em;
|
margin-right: 2em;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-close-bttn {
|
.tab-close-bttn {
|
||||||
|
|||||||
Reference in New Issue
Block a user