Virtual terminal!

This commit is contained in:
jeffser 2024-10-07 02:02:27 -06:00
parent fcb956ff23
commit 29a5251d63
7 changed files with 87 additions and 39 deletions

View File

@ -167,6 +167,18 @@
}
]
},
{
"name": "vte",
"buildsystem": "meson",
"config-opts": ["-Dvapi=false"],
"sources": [
{
"type": "archive",
"url": "https://gitlab.gnome.org/GNOME/vte/-/archive/0.78.0/vte-0.78.0.tar.gz",
"sha256": "82e19d11780fed4b66400f000829ce5ca113efbbfb7975815f26ed93e4c05f2d"
}
]
},
{
"name" : "alpaca",
"builddir" : true,

View File

@ -0,0 +1,33 @@
#chat_widget.py
"""
Handles the terminal widget
"""
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Vte', '3.91')
from gi.repository import Gtk, Vte, GLib, Pango
class terminal(Vte.Terminal):
__gtype_name__ = 'AlpacaTerminal'
def __init__(self, script:list):
super().__init__(css_classes=["terminal"])
self.set_font(Pango.FontDescription.from_string("Monospace 12"))
pty = Vte.Pty.new_sync(Vte.PtyFlags.DEFAULT, None)
self.set_pty(pty)
pty.spawn_async(
GLib.get_current_dir(),
script,
[],
GLib.SpawnFlags.DEFAULT,
None,
None,
-1,
None,
None
)
self.connect('child-exited', lambda *_: print('exited'))

View File

@ -428,43 +428,11 @@ def run_script_response(self, dialog, task, script, language_name):
with open(os.path.join(cache_dir, 'temp_python_script.py'), 'w') as f:
f.write(script)
script = 'python3 {}'.format(os.path.join(cache_dir, 'temp_python_script.py'))
script += '; read -p "\n(Alpaca) {}"'.format(_('Press Enter to close...'))
using_flatpak = shutil.which('flatpak-spawn')
script += '; echo "\n(Alpaca) {}"'.format(_('Script exited'))
if shutil.which('flatpak-spawn'):
script = 'echo "{}\n";'.format(_('The script is contained inside Flatpak')) + script
try:
terminal_to_use = None
if os.path.isfile(os.path.join(config_dir, 'FORCE_TERMINAL')):
with open(os.path.join(config_dir, 'FORCE_TERMINAL'), 'r') as f:
terminal_to_use = f.read().split('\n')[0].split(' ')
else:
terminals = [['kgx', '-e'], ['gnome-terminal', '--'], ['konsole', '-e'], ['xterm', '-e'], ['lxterminal', '-e'], ['kitty', '-e'], ['xfce4-terminal', '-x'], ['alacritty', '-e'], ['yakuake', '-e']]
for terminal in terminals:
result = subprocess.run(
['flatpak-spawn', '--host', 'sh', '-c', f'command -v {terminal[0]}'] if using_flatpak else ['sh' '-c', f'command -v {terminal[0]}'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
if result.returncode == 0:
terminal_to_use = terminal
break
if terminal_to_use:
if using_flatpak:
run_command = ['flatpak-spawn', '--host']
run_command[2:2] = terminal_to_use
else:
run_command = terminal_to_use
if terminal_to_use[0] == 'flatpak':
run_command.append(f'bash -c {script}')
else:
run_command.append('bash')
run_command.append('-c')
run_command.append(script)
subprocess.Popen(run_command)
else:
self.show_toast(_('No compatible terminal was found in the system'), self.main_overlay)
except Exception as e:
logger.error(f'Error running script on {terminal_to_use}: {e}')
self.run_terminal(['bash', '-c', script])
def run_script(self, script:str, language_name:str):
dialog = Adw.AlertDialog(

View File

@ -50,7 +50,8 @@ custom_widgets = [
'custom_widgets/table_widget.py',
'custom_widgets/message_widget.py',
'custom_widgets/chat_widget.py',
'custom_widgets/model_widget.py'
'custom_widgets/model_widget.py',
'custom_widgets/terminal_widget.py'
]
install_data(alpaca_sources, install_dir: moduledir)

View File

@ -36,4 +36,7 @@ stacksidebar {
}
.code_block {
font-family: monospace;
}
}
.terminal {
padding: 10px;
}

View File

@ -32,7 +32,7 @@ gi.require_version('GdkPixbuf', '2.0')
from gi.repository import Adw, Gtk, Gdk, GLib, GtkSource, Gio, GdkPixbuf
from . import dialogs, connection_handler
from .custom_widgets import message_widget, chat_widget, model_widget
from .custom_widgets import message_widget, chat_widget, model_widget, terminal_widget
from .internal import config_dir, data_dir, cache_dir, source_dir
logger = logging.getLogger(__name__)
@ -118,6 +118,9 @@ class AlpacaWindow(Adw.ApplicationWindow):
style_manager = Adw.StyleManager()
terminal_scroller = Gtk.Template.Child()
terminal_dialog = Gtk.Template.Child()
@Gtk.Template.Callback()
def stop_message(self, button=None):
self.chat_list_box.get_current_chat().stop_message()
@ -368,6 +371,10 @@ class AlpacaWindow(Adw.ApplicationWindow):
clipboard.read_text_async(None, self.cb_text_received)
clipboard.read_texture_async(None, self.cb_image_received)
def run_terminal(self, script:list):
self.terminal_scroller.set_child(terminal_widget.terminal(script))
self.terminal_dialog.present(self)
def convert_model_name(self, name:str, mode:int) -> str: # mode=0 name:tag -> Name (tag) | mode=1 Name (tag) -> name:tag
try:
if mode == 0:

View File

@ -475,6 +475,30 @@
</child>
</object>
<object class="AdwDialog" id="terminal_dialog">
<accessibility>
<property name="label" translatable="yes">Manage models dialog</property>
</accessibility>
<property name="title" translatable="yes">Terminal</property>
<property name="can-close">true</property>
<property name="width-request">400</property>
<property name="height-request">600</property>
<child>
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
<style>
<class name="osd"/>
</style>
</object>
</child>
<property name="content">
<object class="GtkScrolledWindow" id="terminal_scroller"></object>
</property>
</object>
</child>
</object>
<object class="AdwDialog" id="manage_models_dialog">
<accessibility>
<property name="label" translatable="yes">Manage models dialog</property>