diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..c29bf06
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,2 @@
+# Berry IDE
+W.I.P
\ No newline at end of file
diff --git a/main.py b/main.py
index 641226c..b8e38c6 100644
--- a/main.py
+++ b/main.py
@@ -10,10 +10,21 @@ from textual_fspicker import FileOpen, FileSave
from plugin_loader import PluginLoader
+from watchdog.observers import Observer
+from watchdog.events import FileSystemEventHandler
+
import subprocess
import os
+class Watcher(FileSystemEventHandler):
+ def __init__(self, app: App):
+ super().__init__()
+ self.app = app
+
+ async def on_any_event(self, event):
+ await self.app.query_one(DirectoryTree).reload()
+
class Berry(App):
CSS_PATH = "assets/style.tcss"
SUB_TITLE = "New File"
@@ -26,6 +37,10 @@ class Berry(App):
Binding("ctrl+f", "find", "Find", priority=True)
]
+ def __init__(self, path: str):
+ super().__init__()
+ self.path = path
+
def compose(self) -> ComposeResult:
yield Header()
with Vertical(id="sidebar"):
@@ -36,7 +51,7 @@ class Berry(App):
with ContentSwitcher(initial="files"):
with Vertical(id="files"):
yield Static("EXPLORER")
- yield DirectoryTree("./", id="directory")
+ yield DirectoryTree(self.path, id="directory")
with Vertical(id="editor"):
first_tab = Tab("New File")
@@ -46,7 +61,7 @@ class Berry(App):
first_tab,
id="file-tabs"
)
- yield TextArea.code_editor(placeholder="This file is empty.", language="python", theme="css", id="code-editor", disabled=True)
+ yield TextArea.code_editor(placeholder="This file is empty.", theme="css", id="code-editor", disabled=True)
#if os.name == "nt":
with Vertical(id="console-container"):
@@ -64,7 +79,7 @@ class Berry(App):
self.run_command(event.input.value)
event.input.clear()
-
+
def run_command(self, command: str):
console = self.query_one("#console")
@@ -248,7 +263,11 @@ class Berry(App):
with open(result, "wb") as f:
f.write(self.query_one("#code-editor").text.encode())
+
+ tabs: Tabs = self.query_one("#file-tabs")
+ tabs.active_tab.label = os.path.basename(result)
self.notify(f"Saved to {result} successfully.", title="Done!", markup=False)
+ self.query_one(DirectoryTree).reload()
def action_save_as(self):
self.push_screen(FileSave(), callback=self.done_saving)
@@ -269,6 +288,11 @@ class Berry(App):
self.unsaved_files.pop(self.open_file)
self.notify("Saved.")
+ def action_quit(self):
+ self.observer.stop()
+ self.observer.join()
+ return super().action_quit()
+
def on_ready(self):
# src/main.py: Tab<>
self.file_tabs = {}
@@ -277,12 +301,15 @@ class Berry(App):
self.switching = False
self.file_clicked = False
+ self.observer = Observer()
+ self.observer.schedule(Watcher(self), path=self.path)
+ self.observer.start()
+
#if os.name == "nt":
self.query_one("#console").write("Run a command below.")
#else:
# self.query_one("#terminal").start()
-
if __name__ == "__main__":
- app = Berry()
+ app = Berry("./")
app.run()
\ No newline at end of file
diff --git a/plugin_loader.py b/plugin_loader.py
index 27a020b..7420d3b 100644
--- a/plugin_loader.py
+++ b/plugin_loader.py
@@ -1,7 +1,8 @@
from textual_window import Window
-from textual.widgets import RichLog
+from textual.widgets import RichLog, Button
from textual import work
-from lupa import LuaRuntime, lua51
+from textual.binding import Binding
+from lupa import lua51
import os, json, asyncio
@@ -18,6 +19,30 @@ class PluginLoader(Window):
allow_maximize=True
)
+ def fake_notify(self, message: str, title: str = None, severity: str = "information"):
+ self.app.notify(message=message, title=title, severity=severity)
+
+ def create_sidebar_button(self, icon: str):
+ new_button = Button(icon)
+ self.app.query_one("#sidebar-buttons").mount(new_button)
+
+ def set_theme(self, theme_name: str):
+ self.app.theme = theme_name
+
+ def add_bind(self, action_name: str, key: str, description: str, show: bool = True):
+ # a bit of a sneaky way of doing things
+ self.app.bind(key, action_name, description=description, show=show)
+ self.app.refresh_bindings()
+
+ def fake_run_action(self, action_name: str):
+ getattr(self.app, f"action_{action_name}")()
+
+ def create_action(self, action_name: str, function):
+ def wrapper():
+ function()
+
+ setattr(self.app, f"action_{action_name}", wrapper)
+
@work
async def find_plugins(self):
log = self.query_one(RichLog)
@@ -26,9 +51,15 @@ class PluginLoader(Window):
log.write("[b]Setting up LUA runtime..[/]")
self.lua_runtime = lua51.LuaRuntime()
+
lua_runtime_stuff = {
"ui": {
- "notify": self.notify
+ "notify": self.fake_notify,
+ "createSidebarButton": self.create_sidebar_button,
+ "setTheme": self.set_theme,
+ "runAction": self.fake_run_action,
+ "addBind": self.add_bind,
+ "createAction": self.create_action
}
}
@@ -109,7 +140,7 @@ class PluginLoader(Window):
executed_code = self.lua_runtime.execute(code)
except lua51.LuaError as e:
log.write(f"[b red]Error in {lua_file_path}: {e}[/]")
- self.notify("There was Lua error while loading one your installed plugins. Check the Plugin Loader window for more details.", title="Lua Error", severity="error")
+ self.notify("There was Lua error while loading one your installed plugins. Check the Plugin Loader window for more details.", title="Lua Error", severity="error", timeout=10)
no_errors = False
continue
@@ -120,8 +151,9 @@ class PluginLoader(Window):
plugin_paths.append(plugin_folder)
+ log.write("\n[b]Done loading plugins![/]")
if no_errors:
- log.write("\n[d]Window will automatically close in 5 seconds.[/]")
+ log.write("[d]Window will automatically close in 5 seconds.[/]")
await asyncio.sleep(5.0)
self.close_window()
diff --git a/plugins/test-plugin/lua/main.lua b/plugins/test-plugin/lua/main.lua
index a3696c0..d45467f 100644
--- a/plugins/test-plugin/lua/main.lua
+++ b/plugins/test-plugin/lua/main.lua
@@ -1,7 +1,12 @@
local plugin = {}
+function testAction()
+ berry.ui.notify("I just ran the test action!")
+end
+
function plugin.init()
- berry.ui.notify(tostring(math.random(1,10)))
+ berry.ui.createAction("test", testAction)
+ berry.ui.addBind("test", "ctrl+d", "Test")
end
return plugin
\ No newline at end of file