Moved plugins and refactor command system
- Moved plugins to apropriate sub folders - Refactor command system with new add_command method and rename GetCommandSystemEvent to GetNewCommandSystemEvent - Add RegisterCommandEvent for dynamic command registration - Change footer container orientation to VERTICAL - Add search-highlight tag to source buffer - Add file change detection (deleted, externally modified) in source_file - Add JSON prettify option to source view popup menu - Enable hexpand on VTE widget - Update plugins_controller_mixin to use widget_registry
This commit is contained in:
@@ -6,8 +6,7 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.dto.base_event import BaseEvent
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
from libs.event_factory import Event_Factory
|
|
||||||
|
|
||||||
from plugins.plugin_types import PluginCode
|
from plugins.plugin_types import PluginCode
|
||||||
|
|
||||||
@@ -22,7 +21,7 @@ class Plugin(PluginCode):
|
|||||||
self.provider: Provider = None
|
self.provider: Provider = None
|
||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: BaseEvent):
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
...
|
...
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
@@ -30,13 +30,13 @@ class Provider(GObject.GObject, GtkSource.CompletionProvider):
|
|||||||
return 'Example Code Completion'
|
return 'Example Code Completion'
|
||||||
|
|
||||||
def do_match(self, context):
|
def do_match(self, context):
|
||||||
# word = context.get_word()
|
# Note: If provider is in interactive activation then need to check
|
||||||
# if not word or len(word) < 2: return False
|
# view focus as otherwise non focus views start trying to grab it.
|
||||||
|
completion = context.get_property("completion")
|
||||||
|
if not completion.get_view().has_focus(): return
|
||||||
|
|
||||||
""" Get whether the provider match the context of completion detailed in context. """
|
|
||||||
word = self.response_cache.get_word(context)
|
word = self.response_cache.get_word(context)
|
||||||
if not word or len(word) < 2: return False
|
if not word or len(word) < 2: return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def do_get_priority(self):
|
def do_get_priority(self):
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
@@ -21,6 +22,9 @@ class ProviderResponseCache(ProviderResponseCacheBase):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ProviderResponseCache, self).__init__()
|
super(ProviderResponseCache, self).__init__()
|
||||||
|
|
||||||
|
# Note: Using asyncio.run causes a keyboard trap that prevents app
|
||||||
|
# closure from terminal. ThreadPoolExecutor seems to not have such issues...
|
||||||
|
self.executor = ThreadPoolExecutor(max_workers = 1)
|
||||||
self.matchers: dict = {
|
self.matchers: dict = {
|
||||||
"hello": {
|
"hello": {
|
||||||
"label": "Hello, World!",
|
"label": "Hello, World!",
|
||||||
@@ -6,8 +6,7 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.dto.base_event import BaseEvent
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
from libs.event_factory import Event_Factory
|
|
||||||
|
|
||||||
from plugins.plugin_types import PluginCode
|
from plugins.plugin_types import PluginCode
|
||||||
|
|
||||||
@@ -22,7 +21,7 @@ class Plugin(PluginCode):
|
|||||||
self.provider: Provider = None
|
self.provider: Provider = None
|
||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: BaseEvent):
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
...
|
...
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
import gi
|
import gi
|
||||||
@@ -17,9 +18,13 @@ class ProviderResponseCache(ProviderResponseCacheBase):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ProviderResponseCache, self).__init__()
|
super(ProviderResponseCache, self).__init__()
|
||||||
|
|
||||||
|
self.executor = ThreadPoolExecutor(max_workers = 1)
|
||||||
|
self.matchers: dict = {}
|
||||||
|
|
||||||
|
|
||||||
def process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
def process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
||||||
...
|
buffer = event.file.buffer
|
||||||
|
self.executor.submit(self._handle_change, buffer)
|
||||||
|
|
||||||
def process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
def process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
||||||
...
|
...
|
||||||
@@ -28,8 +33,13 @@ class ProviderResponseCache(ProviderResponseCacheBase):
|
|||||||
...
|
...
|
||||||
|
|
||||||
def process_file_change(self, event: Code_Event_Types.TextChangedEvent):
|
def process_file_change(self, event: Code_Event_Types.TextChangedEvent):
|
||||||
|
buffer = event.file.buffer
|
||||||
|
self.executor.submit(self._handle_change, buffer)
|
||||||
|
|
||||||
|
def _handle_change(self, buffer):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
def filter(self, word: str) -> list[dict]:
|
def filter(self, word: str) -> list[dict]:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@@ -6,8 +6,7 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.dto.base_event import BaseEvent
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
from libs.event_factory import Event_Factory
|
|
||||||
|
|
||||||
from plugins.plugin_types import PluginCode
|
from plugins.plugin_types import PluginCode
|
||||||
|
|
||||||
@@ -22,7 +21,7 @@ class Plugin(PluginCode):
|
|||||||
self.provider: Provider = None
|
self.provider: Provider = None
|
||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: BaseEvent):
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
...
|
...
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
@@ -6,8 +6,7 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.dto.base_event import BaseEvent
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
from libs.event_factory import Event_Factory
|
|
||||||
|
|
||||||
from plugins.plugin_types import PluginCode
|
from plugins.plugin_types import PluginCode
|
||||||
|
|
||||||
@@ -22,7 +21,7 @@ class Plugin(PluginCode):
|
|||||||
self.provider: Provider = None
|
self.provider: Provider = None
|
||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: BaseEvent):
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
...
|
...
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
@@ -30,6 +30,11 @@ class Provider(GObject.GObject, GtkSource.CompletionProvider):
|
|||||||
return 'Words Completion'
|
return 'Words Completion'
|
||||||
|
|
||||||
def do_match(self, context):
|
def do_match(self, context):
|
||||||
|
# Note: If provider is in interactive activation then need to check
|
||||||
|
# view focus as otherwise non focus views start trying to grab it.
|
||||||
|
completion = context.get_property("completion")
|
||||||
|
if not completion.get_view().has_focus(): return
|
||||||
|
|
||||||
word = self.response_cache.get_word(context)
|
word = self.response_cache.get_word(context)
|
||||||
if not word or len(word) < 2: return False
|
if not word or len(word) < 2: return False
|
||||||
return True
|
return True
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
import asyncio
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
import gi
|
import gi
|
||||||
@@ -24,7 +24,8 @@ class ProviderResponseCache(ProviderResponseCacheBase):
|
|||||||
|
|
||||||
def process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
def process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
||||||
buffer = event.file.buffer
|
buffer = event.file.buffer
|
||||||
asyncio.run( self._handle_change(buffer) )
|
with ThreadPoolExecutor(max_workers = 1) as executor:
|
||||||
|
executor.submit(self._handle_change, buffer)
|
||||||
|
|
||||||
def process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
def process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
||||||
self.matchers[event.file.buffer] = set()
|
self.matchers[event.file.buffer] = set()
|
||||||
@@ -35,13 +36,14 @@ class ProviderResponseCache(ProviderResponseCacheBase):
|
|||||||
|
|
||||||
def process_file_change(self, event: Code_Event_Types.TextChangedEvent):
|
def process_file_change(self, event: Code_Event_Types.TextChangedEvent):
|
||||||
buffer = event.file.buffer
|
buffer = event.file.buffer
|
||||||
asyncio.run( self._handle_change(buffer) )
|
with ThreadPoolExecutor(max_workers = 1) as executor:
|
||||||
|
executor.submit(self._handle_change, buffer)
|
||||||
|
|
||||||
async def _handle_change(self, buffer):
|
def _handle_change(self, buffer):
|
||||||
start_itr = buffer.get_start_iter()
|
start_itr = buffer.get_start_iter()
|
||||||
end_itr = buffer.get_end_iter()
|
end_itr = buffer.get_end_iter()
|
||||||
data = buffer.get_text(start_itr, end_itr, False)
|
data = buffer.get_text(start_itr, end_itr, False)
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
GLib.idle_add(self.load_empty_set, buffer)
|
GLib.idle_add(self.load_empty_set, buffer)
|
||||||
return
|
return
|
||||||
@@ -67,6 +69,9 @@ class ProviderResponseCache(ProviderResponseCacheBase):
|
|||||||
buffer = self.get_iter_correctly(context).get_buffer()
|
buffer = self.get_iter_correctly(context).get_buffer()
|
||||||
word = self.get_word(context).rstrip()
|
word = self.get_word(context).rstrip()
|
||||||
|
|
||||||
|
if not buffer in self.matchers:
|
||||||
|
self.matchers[buffer] = set()
|
||||||
|
|
||||||
response: list[dict] = []
|
response: list[dict] = []
|
||||||
for entry in self.matchers[buffer]:
|
for entry in self.matchers[buffer]:
|
||||||
if not entry.rstrip().startswith(word): continue
|
if not entry.rstrip().startswith(word): continue
|
||||||
@@ -81,7 +86,6 @@ class ProviderResponseCache(ProviderResponseCacheBase):
|
|||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def load_empty_set(self, buffer):
|
def load_empty_set(self, buffer):
|
||||||
self.matchers[buffer] = set()
|
self.matchers[buffer] = set()
|
||||||
|
|
||||||
@@ -8,11 +8,11 @@ from gi.repository import Gtk
|
|||||||
# Application imports
|
# Application imports
|
||||||
from libs.dto.base_event import BaseEvent
|
from libs.dto.base_event import BaseEvent
|
||||||
|
|
||||||
from plugins.plugin_base import PluginBase
|
from plugins.plugin_types import PluginUI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin(PluginBase):
|
class Plugin(PluginUI):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Plugin, self).__init__()
|
super(Plugin, self).__init__()
|
||||||
|
|
||||||
@@ -21,14 +21,14 @@ class Plugin(PluginBase):
|
|||||||
...
|
...
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
ui_element = self.requests_ui_element("plugin_control_list")
|
ui_element = self.requests_ui_element("header-container")
|
||||||
ui_element.add( self.generate_plugin_element() )
|
ui_element.add( self.generate_plugin_element() )
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
...
|
...
|
||||||
|
|
||||||
def generate_plugin_element(self):
|
def generate_plugin_element(self):
|
||||||
button = Gtk.Button(label = self.name)
|
button = Gtk.Button(label = "Hello, World!")
|
||||||
|
|
||||||
button.connect("button-release-event", self.send_message)
|
button.connect("button-release-event", self.send_message)
|
||||||
button.show()
|
button.show()
|
||||||
@@ -36,6 +36,5 @@ class Plugin(PluginBase):
|
|||||||
return button
|
return button
|
||||||
|
|
||||||
def send_message(self, widget = None, eve = None):
|
def send_message(self, widget = None, eve = None):
|
||||||
message = "Hello, World!"
|
logger.info("Hello, World!")
|
||||||
self.emit("display_message", ("warning", message, None))
|
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ class FooterContainer(Gtk.Box):
|
|||||||
self.ctx = self.get_style_context()
|
self.ctx = self.get_style_context()
|
||||||
self.ctx.add_class("footer-container")
|
self.ctx.add_class("footer-container")
|
||||||
|
|
||||||
self.set_orientation(Gtk.Orientation.HORIZONTAL)
|
self.set_orientation(Gtk.Orientation.VERTICAL)
|
||||||
self.set_hexpand(True)
|
self.set_hexpand(True)
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ class CommandSystem:
|
|||||||
method = getattr(commands, command)
|
method = getattr(commands, command)
|
||||||
return method.execute(*args)
|
return method.execute(*args)
|
||||||
|
|
||||||
|
def add_command(self, command_name: str, command: callable):
|
||||||
|
setattr(commands, command_name, command)
|
||||||
|
|
||||||
|
|
||||||
def emit(self, event: Code_Event_Types.CodeEvent):
|
def emit(self, event: Code_Event_Types.CodeEvent):
|
||||||
""" Monkey patch 'emit' from command controller... """
|
""" Monkey patch 'emit' from command controller... """
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ __all__ = []
|
|||||||
|
|
||||||
for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
|
for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
|
||||||
module = importlib.import_module(f"{__name__}.{module_name}")
|
module = importlib.import_module(f"{__name__}.{module_name}")
|
||||||
globals()[module_name] = module # Add module to package namespace
|
# globals()[module_name] = module # Add module to package namespace
|
||||||
__all__.append(module_name)
|
__all__.append(module_name)
|
||||||
|
|
||||||
del pkgutil
|
del pkgutil
|
||||||
|
|||||||
@@ -18,12 +18,7 @@ def execute(
|
|||||||
uri: str
|
uri: str
|
||||||
):
|
):
|
||||||
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.get_file(view)
|
|
||||||
buffer = file.buffer
|
|
||||||
|
|
||||||
if not file.ftype == "buffer":
|
|
||||||
file = view.command.new_file(view)
|
|
||||||
|
|
||||||
gfile = Gio.File.new_for_uri(uri)
|
gfile = Gio.File.new_for_uri(uri)
|
||||||
view.command.exec_with_args(
|
view.command.exec_with_args(
|
||||||
@@ -31,4 +26,5 @@ def execute(
|
|||||||
(view, gfile, file)
|
(view, gfile, file)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
view.set_buffer(file.buffer)
|
||||||
update_info_bar_if_focused(view.command, view)
|
update_info_bar_if_focused(view.command, view)
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ class CommandsController(ControllerBase, list):
|
|||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
if isinstance(event, Code_Event_Types.GetCommandSystemEvent):
|
if isinstance(event, Code_Event_Types.GetNewCommandSystemEvent):
|
||||||
event.response = self.get_command_system()
|
event.response = self.get_new_command_system()
|
||||||
|
|
||||||
def get_command_system(self):
|
def get_new_command_system(self):
|
||||||
command_system = CommandSystem()
|
command_system = CommandSystem()
|
||||||
command_system.emit = self.emit
|
command_system.emit = self.emit
|
||||||
command_system.emit_to = self.emit_to
|
command_system.emit_to = self.emit_to
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ class SourceViewsController(ControllerBase, list):
|
|||||||
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
if isinstance(event, Code_Event_Types.RemovedFileEvent):
|
if isinstance(event, Code_Event_Types.RemovedFileEvent):
|
||||||
self._remove_file(event)
|
self._remove_file(event)
|
||||||
|
elif isinstance(event, Code_Event_Types.RegisterCommandEvent):
|
||||||
|
self. _register_command(event)
|
||||||
|
|
||||||
if not self.signal_mapper.active_view: return
|
if not self.signal_mapper.active_view: return
|
||||||
|
|
||||||
@@ -40,8 +42,22 @@ class SourceViewsController(ControllerBase, list):
|
|||||||
elif isinstance(event, Code_Event_Types.TextInsertedEvent):
|
elif isinstance(event, Code_Event_Types.TextInsertedEvent):
|
||||||
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):
|
||||||
|
self.state_manager.key_mapper.map_command(
|
||||||
|
event.command_name,
|
||||||
|
{
|
||||||
|
f"{event.binding_mode}": event.binding
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
for view in self:
|
||||||
|
view.command.add_command(
|
||||||
|
event.command_name,
|
||||||
|
event.command
|
||||||
|
)
|
||||||
|
|
||||||
def _get_command_system(self):
|
def _get_command_system(self):
|
||||||
event = Event_Factory.create_event("get_command_system")
|
event = Event_Factory.create_event("get_new_command_system")
|
||||||
self.message_to("commands", event)
|
self.message_to("commands", event)
|
||||||
command = event.response
|
command = event.response
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from ...key_mapper import KeyMapper
|
|||||||
from .states import *
|
from .states import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SourceViewStateManager:
|
class SourceViewStateManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.key_mapper: KeyMapper = KeyMapper()
|
self.key_mapper: KeyMapper = KeyMapper()
|
||||||
|
|||||||
@@ -70,29 +70,31 @@ class KeyMapper:
|
|||||||
|
|
||||||
with open(bindings_file, 'r') as f:
|
with open(bindings_file, 'r') as f:
|
||||||
data = json.load(f)["keybindings"]
|
data = json.load(f)["keybindings"]
|
||||||
|
|
||||||
for command in data:
|
for command in data:
|
||||||
press_state = "held" if "held" in data[command] else "released"
|
self.map_command( command, data[command] )
|
||||||
keyname = data[command][press_state]
|
|
||||||
|
|
||||||
state = NoKeyState
|
|
||||||
if "<Control>" in keyname:
|
|
||||||
state = state | CtrlKeyState
|
|
||||||
if "<Shift>" in keyname:
|
|
||||||
state = state | ShiftKeyState
|
|
||||||
if "<Alt>" in keyname:
|
|
||||||
state = state | AltKeyState
|
|
||||||
|
|
||||||
keyname = keyname.replace("<Control>", "") \
|
|
||||||
.replace("<Shift>", "") \
|
|
||||||
.replace("<Alt>", "") \
|
|
||||||
.lower()
|
|
||||||
|
|
||||||
getattr(self.states[state], press_state)[keyname] = command
|
|
||||||
|
|
||||||
def re_map(self):
|
def re_map(self):
|
||||||
self.states = copy.deepcopy(self._map)
|
self.states = copy.deepcopy(self._map)
|
||||||
|
|
||||||
|
def map_command(self, command, entry):
|
||||||
|
press_state = "held" if "held" in entry else "released"
|
||||||
|
keyname = entry[press_state]
|
||||||
|
|
||||||
|
state = NoKeyState
|
||||||
|
if "<Control>" in keyname:
|
||||||
|
state = state | CtrlKeyState
|
||||||
|
if "<Shift>" in keyname:
|
||||||
|
state = state | ShiftKeyState
|
||||||
|
if "<Alt>" in keyname:
|
||||||
|
state = state | AltKeyState
|
||||||
|
|
||||||
|
keyname = keyname.replace("<Control>", "") \
|
||||||
|
.replace("<Shift>", "") \
|
||||||
|
.replace("<Alt>", "") \
|
||||||
|
.lower()
|
||||||
|
|
||||||
|
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 = Gdk.keyval_name(eve.keyval).lower()
|
||||||
|
|
||||||
|
|||||||
@@ -13,9 +13,14 @@ class SourceBuffer(GtkSource.Buffer):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(SourceBuffer, self).__init__()
|
super(SourceBuffer, self).__init__()
|
||||||
|
|
||||||
|
self._handler_ids = []
|
||||||
self.is_processing_completion: bool = False
|
self.is_processing_completion: bool = False
|
||||||
|
|
||||||
self._handler_ids = []
|
self.create_tag(
|
||||||
|
"search-highlight",
|
||||||
|
background = "yellow",
|
||||||
|
foreground = "black"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def set_signals(
|
def set_signals(
|
||||||
|
|||||||
@@ -43,10 +43,26 @@ class SourceFile(GtkSource.File):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _changed(self, buffer: SourceBuffer):
|
def _changed(self, buffer: SourceBuffer):
|
||||||
|
self.check_file_on_disk()
|
||||||
|
|
||||||
event = Event_Factory.create_event("text_changed", buffer = buffer)
|
event = Event_Factory.create_event("text_changed", buffer = buffer)
|
||||||
event.file = self
|
event.file = self
|
||||||
self.emit(event)
|
self.emit(event)
|
||||||
|
|
||||||
|
if self.is_deleted():
|
||||||
|
print("deleted")
|
||||||
|
# event = Event_Factory.create_event("file_deleted", buffer = buffer)
|
||||||
|
# event.file = self
|
||||||
|
# self.emit(event)
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_externally_modified():
|
||||||
|
print("is_externally_modified")
|
||||||
|
# event = Event_Factory.create_event("file_externally_modified", buffer = buffer)
|
||||||
|
# event.file = self
|
||||||
|
# self.emit(event)
|
||||||
|
return
|
||||||
|
|
||||||
def _insert_text(
|
def _insert_text(
|
||||||
self,
|
self,
|
||||||
buffer: SourceBuffer,
|
buffer: SourceBuffer,
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class SourceView(GtkSource.View, SourceViewDnDMixin):
|
|||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
self.connect("drag-data-received", self._on_drag_data_received)
|
self.connect("drag-data-received", self._on_drag_data_received)
|
||||||
|
self.connect("populate-popup", self._on_populate_popup)
|
||||||
|
|
||||||
def _subscribe_to_events(self):
|
def _subscribe_to_events(self):
|
||||||
...
|
...
|
||||||
@@ -76,6 +77,37 @@ class SourceView(GtkSource.View, SourceViewDnDMixin):
|
|||||||
|
|
||||||
self._set_up_dnd()
|
self._set_up_dnd()
|
||||||
|
|
||||||
|
def _on_populate_popup(self, view, menu):
|
||||||
|
buffer = self.get_buffer()
|
||||||
|
language = buffer.get_language()
|
||||||
|
|
||||||
|
if language.get_id() == "json":
|
||||||
|
self._load_prettify_json(view, menu)
|
||||||
|
|
||||||
|
menu.show_all()
|
||||||
|
|
||||||
|
def _load_prettify_json(self, view, menu):
|
||||||
|
menu.append( Gtk.SeparatorMenuItem() )
|
||||||
|
|
||||||
|
def on_prettify_json(menuitem):
|
||||||
|
import json
|
||||||
|
|
||||||
|
buffer = self.get_buffer()
|
||||||
|
start_itr, \
|
||||||
|
end_itr = buffer.get_start_iter(), buffer.get_end_iter()
|
||||||
|
data = buffer.get_text(start_itr, end_itr, False)
|
||||||
|
text = json.dumps(json.loads(data), separators = (',', ':'), indent = 4)
|
||||||
|
|
||||||
|
buffer.begin_user_action()
|
||||||
|
buffer.delete(start_itr, end_itr)
|
||||||
|
buffer.insert(start_itr, text)
|
||||||
|
buffer.end_user_action()
|
||||||
|
|
||||||
|
item = Gtk.MenuItem(label = "Prettify JSON")
|
||||||
|
item.connect("activate", on_prettify_json)
|
||||||
|
menu.append(item)
|
||||||
|
|
||||||
|
|
||||||
def clear_temp_cut_buffer_delayed(self):
|
def clear_temp_cut_buffer_delayed(self):
|
||||||
if self._cut_temp_timeout_id:
|
if self._cut_temp_timeout_id:
|
||||||
GLib.source_remove(self._cut_temp_timeout_id)
|
GLib.source_remove(self._cut_temp_timeout_id)
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class VteWidget(Vte.Terminal):
|
|||||||
ctx.add_class("vte-widget")
|
ctx.add_class("vte-widget")
|
||||||
|
|
||||||
self.set_clear_background(False)
|
self.set_clear_background(False)
|
||||||
|
self.set_hexpand(True)
|
||||||
self.set_enable_sixel(True)
|
self.set_enable_sixel(True)
|
||||||
self.set_cursor_shape( Vte.CursorShape.IBEAM )
|
self.set_cursor_shape( Vte.CursorShape.IBEAM )
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,9 @@
|
|||||||
|
|
||||||
from .code_event import CodeEvent
|
from .code_event import CodeEvent
|
||||||
from .register_provider_event import RegisterProviderEvent
|
from .register_provider_event import RegisterProviderEvent
|
||||||
|
from .register_command_event import RegisterCommandEvent
|
||||||
|
|
||||||
from .get_command_system_event import GetCommandSystemEvent
|
from .get_new_command_system_event import GetNewCommandSystemEvent
|
||||||
from .request_completion_event import RequestCompletionEvent
|
from .request_completion_event import RequestCompletionEvent
|
||||||
from .cursor_moved_event import CursorMovedEvent
|
from .cursor_moved_event import CursorMovedEvent
|
||||||
from .modified_changed_event import ModifiedChangedEvent
|
from .modified_changed_event import ModifiedChangedEvent
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ from .code_event import CodeEvent
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class GetCommandSystemEvent(CodeEvent):
|
class GetNewCommandSystemEvent(CodeEvent):
|
||||||
...
|
...
|
||||||
20
src/libs/dto/code/register_command_event.py
Normal file
20
src/libs/dto/code/register_command_event.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Python imports
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
import gi
|
||||||
|
gi.require_version('GtkSource', '4')
|
||||||
|
|
||||||
|
from gi.repository import GtkSource
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from ..base_event import BaseEvent
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RegisterCommandEvent(BaseEvent):
|
||||||
|
command_name: str = ""
|
||||||
|
command: callable = None
|
||||||
|
binding_mode: str = ""
|
||||||
|
binding: str = ""
|
||||||
@@ -14,10 +14,7 @@ class InvalidPluginException(Exception):
|
|||||||
class PluginsControllerMixin:
|
class PluginsControllerMixin:
|
||||||
|
|
||||||
def requests_ui_element(self, target_id: str):
|
def requests_ui_element(self, target_id: str):
|
||||||
builder = settings_manager.get_builder()
|
if not target_id in widget_registery.objects:
|
||||||
ui_target = builder.get_object(target_id)
|
raise InvalidPluginException('Unknown UI "target_id" given in requests.')
|
||||||
|
|
||||||
if not ui_target:
|
return widget_registery.objects[target_id]
|
||||||
raise InvalidPluginException('Unknown "target_id" given in requests.')
|
|
||||||
|
|
||||||
return ui_target
|
|
||||||
|
|||||||
Reference in New Issue
Block a user