Added more commands to code; refactored container classes; general cleanup

This commit is contained in:
2025-12-15 22:50:28 -06:00
parent 849e7611ca
commit c16493037d
34 changed files with 469 additions and 88 deletions

View File

@@ -16,8 +16,6 @@ class BaseContainer(Gtk.Box):
def __init__(self):
super(BaseContainer, self).__init__()
self.ctx = self.get_style_context()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
@@ -27,9 +25,11 @@ class BaseContainer(Gtk.Box):
def _setup_styling(self):
self.set_orientation(Gtk.Orientation.VERTICAL)
self.ctx = self.get_style_context()
self.ctx.add_class("base-container")
self.set_orientation(Gtk.Orientation.VERTICAL)
def _setup_signals(self):
...

View File

@@ -16,8 +16,6 @@ class BodyContainer(Gtk.Box):
def __init__(self):
super(BodyContainer, self).__init__()
self.ctx = self.get_style_context()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
@@ -27,8 +25,10 @@ class BodyContainer(Gtk.Box):
def _setup_styling(self):
self.set_orientation(Gtk.Orientation.HORIZONTAL)
self.ctx = self.get_style_context()
self.ctx.add_class("body-container")
self.set_orientation(Gtk.Orientation.HORIZONTAL)
self.set_homogeneous(True)
def _setup_signals(self):
@@ -37,7 +37,6 @@ class BodyContainer(Gtk.Box):
def _subscribe_to_events(self):
...
def _load_widgets(self):
self.add( LeftContainer() )
self.add( CenterContainer() )

View File

@@ -25,14 +25,13 @@ class CenterContainer(Gtk.Box):
def _setup_styling(self):
self.set_orientation(Gtk.Orientation.VERTICAL)
self.ctx = self.get_style_context()
self.ctx.add_class("center-container")
self.set_orientation(Gtk.Orientation.VERTICAL)
self.set_hexpand(True)
self.set_vexpand(True)
ctx = self.get_style_context()
ctx.add_class("center-container")
def _setup_signals(self):
...

View File

@@ -0,0 +1,3 @@
"""
Containers Package
"""

View File

@@ -0,0 +1,40 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from ...widgets.separator_widget import Separator
from ...widgets.code.miniview_widget import MiniViewWidget
from .paned_editors_container import PanedEditorsContainer
class EditorsContainer(Gtk.Box):
def __init__(self):
super(EditorsContainer, self).__init__()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets()
self.show()
def _setup_styling(self):
...
def _setup_signals(self):
...
def _subscribe_to_events(self):
...
def _load_widgets(self):
self.add( Separator("separator_left") )
self.add( PanedEditorsContainer() )
self.add( Separator("separator_right") )
self.add( MiniViewWidget() )

View File

@@ -0,0 +1,75 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GLib
# Application imports
from ...widgets.code.view import SourceView
class PanedEditorsContainer(Gtk.Paned):
def __init__(self):
super(PanedEditorsContainer, self).__init__()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets()
self.show()
def _setup_styling(self):
self.ctx = self.get_style_context()
self.ctx.add_class("paned-editors-container")
self.set_hexpand(True)
self.set_vexpand(True)
# self.set_homogeneous(True)
self.set_wide_handle(True)
def _setup_signals(self):
self.map_id = self.connect("map", self._init_map)
def _subscribe_to_events(self):
...
def _load_widgets(self):
scrolled_win1 = Gtk.ScrolledWindow()
scrolled_win2 = Gtk.ScrolledWindow()
source_view1 = SourceView()
source_view2 = SourceView()
source_view1.sibling_right = source_view2
source_view2.sibling_left = source_view1
scrolled_win1.add( source_view1 )
scrolled_win2.add( source_view2 )
self.add1(scrolled_win1)
self.add2(scrolled_win2)
scrolled_win1.show_all()
scrolled_win2.show_all()
def _init_map(self, view):
def _first_show_init():
self.disconnect(self.map_id)
del self.map_id
self._handle_first_show()
return False
# GLib.timeout_add(1000, _first_show_init)
GLib.idle_add(_first_show_init)
def _handle_first_show(self):
self.set_position(
self.get_allocated_width() / 2
)

View File

@@ -13,8 +13,6 @@ class FooterContainer(Gtk.Box):
def __init__(self):
super(FooterContainer, self).__init__()
self.ctx = self.get_style_context()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
@@ -24,12 +22,12 @@ class FooterContainer(Gtk.Box):
def _setup_styling(self):
self.set_orientation(Gtk.Orientation.HORIZONTAL)
self.set_hexpand(True)
self.ctx = self.get_style_context()
self.ctx.add_class("footer-container")
self.set_orientation(Gtk.Orientation.HORIZONTAL)
self.set_hexpand(True)
def _setup_signals(self):
...

View File

@@ -15,8 +15,6 @@ class HeaderContainer(Gtk.Box):
def __init__(self):
super(HeaderContainer, self).__init__()
self.ctx = self.get_style_context()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
@@ -26,19 +24,18 @@ class HeaderContainer(Gtk.Box):
def _setup_styling(self):
self.set_orientation(Gtk.Orientation.HORIZONTAL)
self.set_hexpand(True)
self.ctx = self.get_style_context()
self.ctx.add_class("header-container")
self.set_orientation(Gtk.Orientation.HORIZONTAL)
self.set_hexpand(True)
def _setup_signals(self):
...
def _subscribe_to_events(self):
event_system.subscribe("tggl-top-main-menubar", self.tggl_top_main_menubar)
def _load_widgets(self):
button = Gtk.Button(label = "Interactive Debug")
button.connect("clicked", self._interactive_debug)

View File

@@ -22,13 +22,12 @@ class LeftContainer(Gtk.Box):
def _setup_styling(self):
self.ctx = self.get_style_context()
self.ctx.add_class("left-container")
self.set_orientation(Gtk.Orientation.VERTICAL)
self.set_vexpand(True)
ctx = self.get_style_context()
ctx.add_class("left-container")
def _setup_signals(self):
...

View File

@@ -23,13 +23,12 @@ class RightContainer(Gtk.Box):
def _setup_styling(self):
self.ctx = self.get_style_context()
self.ctx.add_class("right-container")
self.set_orientation(Gtk.Orientation.VERTICAL)
self.set_vexpand(True)
ctx = self.get_style_context()
ctx.add_class("right-container")
def _setup_signals(self):
...

View File

@@ -12,8 +12,7 @@ from gi.repository import GtkSource
def execute(
editor: GtkSource.View = None,
buffer: GtkSource.Buffer= None
editor: GtkSource.View = None
):
logger.debug("Close File Command")
file = editor.files.new()

View File

@@ -0,0 +1,19 @@
# Python imports
# Lib imports
import gi
gi.require_version('GtkSource', '4')
from gi.repository import GtkSource
# Application imports
def execute(
editor: GtkSource.View = None
):
logger.debug("Focus Left Sibling Command")
if not editor.sibling_left: return
editor.sibling_left.grab_focus()

View File

@@ -0,0 +1,19 @@
# Python imports
# Lib imports
import gi
gi.require_version('GtkSource', '4')
from gi.repository import GtkSource
# Application imports
def execute(
editor: GtkSource.View = None
):
logger.debug("Focus Right Sibling Command")
if not editor.sibling_right: return
editor.sibling_right.grab_focus()

View File

@@ -12,8 +12,7 @@ from gi.repository import GtkSource
def execute(
editor: GtkSource.View = None,
buffer: GtkSource.Buffer= None
editor: GtkSource.View = None
):
logger.debug("Line Up Command")
editor.emit("move-lines", True)

View File

@@ -12,8 +12,7 @@ from gi.repository import GtkSource
def execute(
editor: GtkSource.View = None,
buffer: GtkSource.Buffer= None
editor: GtkSource.View = None
):
logger.debug("Line Up Command")
editor.emit("move-lines", False)

View File

@@ -0,0 +1,26 @@
# Python imports
# Lib imports
import gi
gi.require_version('GtkSource', '4')
from gi.repository import GtkSource
# Application imports
def execute(
editor: GtkSource.View = None
):
logger.debug("Move To Left Sibling Command")
if not editor.sibling_left: return
buffer = editor.get_buffer()
sibling_file, popped_file = editor.files.pop_file(buffer)
editor.set_buffer(sibling_file.buffer)
editor.sibling_left.set_buffer(buffer)
editor.sibling_left.files.append(popped_file)
editor.sibling_left.grab_focus()

View File

@@ -0,0 +1,27 @@
# Python imports
# Lib imports
import gi
gi.require_version('GtkSource', '4')
from gi.repository import GtkSource
# Application imports
def execute(
editor: GtkSource.View = None
):
logger.debug("Move To Right Sibling Command")
if not editor.sibling_right: return
buffer = editor.get_buffer()
sibling_file, popped_file = editor.files.pop_file(buffer)
editor.set_buffer(sibling_file.buffer)
editor.sibling_right.set_buffer(buffer)
editor.sibling_right.files.append(popped_file)
editor.sibling_right.grab_focus()

View File

@@ -12,8 +12,7 @@ from gi.repository import GtkSource
def execute(
editor: GtkSource.View = None,
buffer: GtkSource.Buffer= None
editor: GtkSource.View = None
):
logger.debug("New File Command")
file = editor.files.new()

View File

@@ -12,17 +12,16 @@ from gi.repository import GtkSource
def execute(
editor: GtkSource.View = None,
buffer: GtkSource.Buffer= None
editor: GtkSource.View = None
):
logger.debug("Open File(s) Command")
gfiles = event_system.emit_and_await("open_files")
gfiles = event_system.emit_and_await("open-files")
if not gfiles: return
size = len(gfiles)
for i, gfile in enumerate(gfiles):
file = editor.files.new()
file.set_path(gfile)
file.load_path(gfile)
language = editor.language_manager \
.guess_language(file.fname, None)

View File

@@ -0,0 +1,30 @@
# Python imports
# Lib imports
import gi
gi.require_version('GtkSource', '4')
from gi.repository import GtkSource
# Application imports
def execute(
editor: GtkSource.View = None
):
logger.debug("Save File Command")
buffer = editor.get_buffer()
file = editor.files.get_file(buffer)
if file.ftype == "buffer":
file.save_as()
language = editor.language_manager \
.guess_language(file.fname, None)
file.ftype = language
file.buffer.set_language(language)
return
file.save()

View File

@@ -0,0 +1,26 @@
# Python imports
# Lib imports
import gi
gi.require_version('GtkSource', '4')
from gi.repository import GtkSource
# Application imports
def execute(
editor: GtkSource.View = None
):
logger.info("Save File As Command")
buffer = editor.get_buffer()
file = editor.files.get_file(buffer)
file.save_as()
language = editor.language_manager \
.guess_language(file.fname, None)
file.ftype = language
file.buffer.set_language(language)

View File

@@ -12,7 +12,7 @@ from gi.repository import GtkSource
def execute(
editor: GtkSource.View = None,
buffer: GtkSource.Buffer= None
editor: GtkSource.View = None
):
logger.debug("Show Completion Command")
editor.completion.request_completion()

View File

@@ -5,30 +5,33 @@ import gi
from gi.repository import GLib
# Application imports
from .custom_completion_providers.lsp_completion_provider import LSPCompletionProvider
from .completion_providers.example_completion_provider import ExampleCompletionProvider
from .completion_providers.lsp_completion_provider import LSPCompletionProvider
class CompletionManager():
def __init__(self, completer):
def __init__(self):
super(CompletionManager, self).__init__()
self._completor = completer
self._lsp_provider = LSPCompletionProvider()
self._timeout_id = None
def set_completer(self, completer):
self._completor = completer
def request_completion(self):
if self._timeout_id:
GLib.source_remove(self._timeout_id)
self._timeout_id = GLib.timeout_add(
1000,
800,
self._process_request_completion
)
def _process_request_completion(self):
print('hello')
self._start_completion()
self._timeout_id = None
return False
@@ -51,11 +54,12 @@ class CompletionManager():
"""
Note: Use IF NO providers have been added to completion...
"""
self._completion.start(
self._completor.start(
[
ExampleCompletionProvider(),
self._lsp_provider
],
self._completion.create_context()
self._completor.create_context()
)

View File

@@ -19,14 +19,14 @@ class ExampleCompletionProvider(GObject.GObject, GtkSource.CompletionProvider):
This is a custom Completion Example Provider.
# NOTE: used information from here --> https://warroom.rsmus.com/do-that-auto-complete/
"""
__gtype_name__ = 'CustomProvider'
__gtype_name__ = 'ExampleCompletionProvider'
def __init__(self):
GObject.Object.__init__(self)
def do_get_name(self):
""" Returns: a new string containing the name of the provider. """
return _('ExampleProvider')
return 'Example Completion Provider'
def do_match(self, context):
""" Get whether the provider match the context of completion detailed in context. """
@@ -34,6 +34,16 @@ class ExampleCompletionProvider(GObject.GObject, GtkSource.CompletionProvider):
# TODO: Fix me
return True
def do_get_priority(self):
""" Determin position in result list along other providor results. """
return 1
# def do_get_activation(self):
# """ The context for when a provider will show results """
# return GtkSource.CompletionActivation.NONE
# return GtkSource.CompletionActivation.USER_REQUESTED
# return GtkSource.CompletionActivation.INTERACTIVE
def do_populate(self, context):
"""
In this instance, it will do 2 things:
@@ -46,7 +56,7 @@ class ExampleCompletionProvider(GObject.GObject, GtkSource.CompletionProvider):
"""
proposals = [
# GtkSource.CompletionItem(label='Hello World!', text = 'Hello World!', icon = None, info = None) # NOTE: Always proposed...
GtkSource.CompletionItem(label='Hello World!', text = 'Hello World!', icon = None, info = None) # NOTE: Always proposed...
]
# Gtk Versions differ on get_iter responses...

View File

@@ -28,6 +28,9 @@ class LSPCompletionProvider(GObject.Object, GtkSource.CompletionProvider):
self.lsp_data = None
def pre_populate(self, context):
...
def do_get_name(self):
return "LSP Code Completion"
@@ -35,19 +38,36 @@ class LSPCompletionProvider(GObject.Object, GtkSource.CompletionProvider):
return context.get_iter()[1] if isinstance(context.get_iter(), tuple) else context.get_iter()
def do_match(self, context):
iter = self.get_iter_correctly(context)
iter.backward_char()
buffer = iter.get_buffer()
if buffer.get_context_classes_at_iter(iter) != ['no-spell-check']:
return False
ch = iter.get_char()
# NOTE: Look to re-add or apply supprting logic to use spaces
# As is it slows down the editor in certain contexts...
# if not (ch in ('_', '.', ' ') or ch.isalnum()):
if not (ch in ('_', '.') or ch.isalnum()):
return False
return True
def do_get_priority(self):
return 1
def do_get_activation(self):
return GtkSource.CompletionActivation.USER_REQUESTED
return 5
def do_populate(self, context, items = []):
self.lsp_data
# self.lsp_data
proposals = []
comp_item = GtkSource.CompletionItem.new()
comp_item.set_label("LSP Class")
comp_item.set_text("LSP Code")
# comp_item.set_icon(self.get_icon_for_type(completion.type))
comp_item.set_info("A test LSP completion item...")
context.add_proposals(self, [comp_item], True)

View File

@@ -93,15 +93,14 @@ class KeyMapper:
self.states = copy.deepcopy(self._map)
def _key_press_event(self, eve):
keyname = Gdk.keyval_name(eve.keyval)
print(keyname)
keyname = Gdk.keyval_name(eve.keyval).lower()
self._set_key_state(eve)
if keyname in self.states[self.state].held:
return self.states[self.state].held[keyname]
def _key_release_event(self, eve):
keyname = Gdk.keyval_name(eve.keyval)
keyname = Gdk.keyval_name(eve.keyval).lower()
self._set_key_state(eve)
if keyname in self.states[self.state].released:

View File

@@ -0,0 +1,40 @@
# Python imports
# Lib imports
import gi
gi.require_version('GtkSource', '4')
from gi.repository.GtkSource import Map
# Application imports
class MiniViewWidget(Map):
def __init__(self):
super(MiniViewWidget, self).__init__()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets()
self.show_all()
def _setup_styling(self):
self.set_hexpand(False)
ctx = self.get_style_context()
ctx.add_class("mini-view")
def _setup_signals(self):
...
def _subscribe_to_events(self):
event_system.subscribe(f"set-mini-view", self.set_smini_view)
def _load_widgets(self):
...
def set_smini_view(self, source_view):
self.set_view(source_view)

View File

@@ -30,16 +30,20 @@ class SourceFile(GtkSource.File):
self._set_signals()
def set_path(self, gfile: Gio.File.new_for_path):
def load_path(self, gfile: Gio.File):
if not gfile: return
self.set_path(gfile)
data = gfile.load_bytes()[0].get_data().decode("UTF-8")
self.buffer.insert_at_cursor(data)
def set_path(self, gfile: Gio.File):
if not gfile: return
self.set_location(gfile)
self.fpath = gfile.get_parent().get_path(),
self.fname = gfile.get_basename()
data = gfile.load_bytes()[0].get_data().decode("UTF-8")
self.buffer.insert_at_cursor(data)
def _set_signals(self):
self.buffer.set_signals(
@@ -73,5 +77,30 @@ class SourceFile(GtkSource.File):
def _modified_changed(self, buffer: SourceBuffer):
logger.info("SourceFile._modified_changed")
def _write_file(self, gfile: Gio.File):
if not gfile: return
with open(gfile.get_path(), 'w') as f:
start_itr = self.buffer.get_start_iter()
end_itr = self.buffer.get_end_iter()
text = self.buffer.get_text(start_itr, end_itr, True)
f.write(text)
return gfile
def save(self):
self._write_file( self.get_location() )
def save_as(self):
print("poop")
file = event_system.emit_and_await("save-file-dialog")
if not file: return
self._write_file(file)
self.set_path(file)
return file
def close(self):
del self.buffer

View File

@@ -24,6 +24,28 @@ class SourceFilesManager(list):
super().append(file)
def get_file(self, buffer: SourceBuffer):
if not buffer: return
for i, file in enumerate(self):
if not buffer == file.buffer: continue
return file
def pop_file(self, buffer: SourceBuffer):
if not buffer: return
for i, file in enumerate(self):
if not buffer == file.buffer: continue
popped_file = self.pop(i)
sibling_file = None
if len(self) == 0:
sibling_file = self.new()
else:
sibling_file = self[ i - 1 if i > 0 else i + 1]
return sibling_file, popped_file
def remove_file(self, buffer: SourceBuffer):
if not buffer: return

View File

@@ -16,10 +16,13 @@ from .command_system import CommandSystem
from .key_mapper import KeyMapper
class SourceView(GtkSource.View):
def __init__(self):
super(SourceView, self).__init__()
self.sibling_right = None
self.sibling_left = None
self.key_mapper = KeyMapper()
self._setup_styles()
@@ -84,14 +87,18 @@ class SourceView(GtkSource.View):
self.style_scheme_manager = GtkSource.StyleSchemeManager()
self.command = CommandSystem()
self.files = SourceFilesManager()
self.completion = CompletionManager(
self.get_completion()
self.completion = CompletionManager()
self.completion.set_completer( self.get_completion() )
self.style_scheme_manager.append_search_path(
f"{settings_manager.get_home_config_path()}/code_styles"
)
self.syntax_theme = self.style_scheme_manager.get_scheme(
f"{settings.theming.syntax_theme}"
)
self.style_scheme_manager.append_search_path(f"{settings_manager.get_home_config_path()}/code_styles")
self.syntax_theme = self.style_scheme_manager.get_scheme("penguins-in-space")
self.command.set_data(self, self.get_buffer())
self.command.set_data(self)
self.exec_command("new_file")
def _key_press_event(self, view, eve):
@@ -108,8 +115,5 @@ class SourceView(GtkSource.View):
self.exec_command(command)
return True
def _show_completion(self, view):
self.completion.request_completion()
def exec_command(self, command: str):
self.command.exec(command)

View File

@@ -35,7 +35,7 @@ class OpenFilesButton(Gtk.Button):
self.connect("button-release-event", self._open_files)
def _subscribe_to_events(self):
event_system.subscribe("open_files", self._open_files)
event_system.subscribe("open-files", self._open_files)
def _load_widgets(self):
...

View File

@@ -9,6 +9,8 @@ from dataclasses import dataclass
@dataclass
class Theming:
transparency: int = 64
default_zoom: int = 12
syntax_theme: str = "penguins-in-space"
success_color: str = "#88cc27"
warning_color: str = "#ffa800"
error_color: str = "#ff0000"