diff --git a/biscuit/__main__.py b/biscuit/__main__.py index 0313bb02..e655c111 100644 --- a/biscuit/__main__.py +++ b/biscuit/__main__.py @@ -11,8 +11,3 @@ app = App(sys.argv[0], dir=dir) app.run() - - - - - diff --git a/biscuit/core/api/__init__.py b/biscuit/core/api/__init__.py index 96db43a9..042f755e 100644 --- a/biscuit/core/api/__init__.py +++ b/biscuit/core/api/__init__.py @@ -42,3 +42,4 @@ def __init__(self, base: App) -> None: self.register_game = self.base.register_game self.register_langserver = self.base.register_langserver + self.register_run_command = self.base.register_run_command diff --git a/biscuit/core/components/editors/editor.py b/biscuit/core/components/editors/editor.py index 0fc4b0f9..fc1b6b92 100644 --- a/biscuit/core/components/editors/editor.py +++ b/biscuit/core/components/editors/editor.py @@ -14,7 +14,7 @@ def __init__(self, master, path=None, path2=None, editable=True, *args, **kwargs self.showpath = False self.content = None self.diff = False - self.run_command = "" + self.run_command_value = "" self.language = "" self.__buttons__ = [] diff --git a/biscuit/core/components/editors/texteditor/__init__.py b/biscuit/core/components/editors/texteditor/__init__.py index ed021a64..f30077fc 100644 --- a/biscuit/core/components/editors/texteditor/__init__.py +++ b/biscuit/core/components/editors/texteditor/__init__.py @@ -4,6 +4,7 @@ from ...utils import Scrollbar from ..editor import BaseEditor from .linenumbers import LineNumbers +from .menu import RunMenu from .minimap import Minimap from .text import Text @@ -16,6 +17,7 @@ def __init__(self, master, path=None, exists=True, language=None, minimalist=Fal self.language = language self.exists = exists self.editable = True + self.run_command_value = None self.__buttons__ = [('sync', self.base.editorsmanager.reopen_active_editor),] @@ -36,9 +38,15 @@ def __init__(self, master, path=None, exists=True, language=None, minimalist=Fal self.text.load_file() self.text.update_idletasks() - if c := self.base.exec_manager.get_command(self): - self.run_command = c - self.__buttons__.insert(0, ('run', self.run_file)) + self.run_command_value = self.base.exec_manager.get_command(self) + self.__buttons__.insert(0, ('run', self.run_file)) + + self.runmenu = RunMenu(self, "run menu") + if self.run_command_value: + self.runmenu.add_command(f"Run {self.language} file", lambda: self.run_file()) + self.runmenu.add_command("Configure Run...", lambda: self.base.events.show_run_config_palette(self.run_command_value)) + + self.__buttons__.insert(1, ('chevron-down', self.runmenu.show)) self.linenumbers.attach(self.text) if not self.minimalist: @@ -62,10 +70,19 @@ def __init__(self, master, path=None, exists=True, language=None, minimalist=Fal self.auto_save() def run_file(self, *_): + if not self.run_command_value: + self.base.notifications.show("No programs are configured to run this file.") + self.base.events.show_run_config_palette(self.run_command_value) + return + self.save() self.base.panel.show_terminal() self.base.exec_manager.run_command(self) + def set_run_command(self, command): + self.run_command_value = command + self.run_file() + def on_change(self, *_): self.linenumbers.redraw() try: diff --git a/biscuit/core/components/editors/texteditor/menu.py b/biscuit/core/components/editors/texteditor/menu.py new file mode 100644 index 00000000..e9fa1e82 --- /dev/null +++ b/biscuit/core/components/editors/texteditor/menu.py @@ -0,0 +1,6 @@ +from biscuit.core.components.floating import Menu + + +class RunMenu(Menu): + def get_coords(self, e) -> list: + return e.widget.winfo_rootx() + e.widget.winfo_width() - self.winfo_width(), e.widget.winfo_rooty() + e.widget.winfo_height() diff --git a/biscuit/core/components/floating/menu/__init__.py b/biscuit/core/components/floating/menu/__init__.py index 9256c2b4..18ae642a 100644 --- a/biscuit/core/components/floating/menu/__init__.py +++ b/biscuit/core/components/floating/menu/__init__.py @@ -61,6 +61,9 @@ def add_item(self, text, command=lambda *_:...): self.menu_items.append(new_item) self.row += 1 + + def add_command(self, *args, **kwargs): + self.add_item(*args, **kwargs) def add_separator(self, length=18): new_sep = Separator(self.container, length) diff --git a/biscuit/core/components/floating/palette/__init__.py b/biscuit/core/components/floating/palette/__init__.py index 9a2a967d..1e520114 100644 --- a/biscuit/core/components/floating/palette/__init__.py +++ b/biscuit/core/components/floating/palette/__init__.py @@ -155,7 +155,7 @@ def show_items(self, items: list[PaletteItem]) -> None: self.reset_selection() - def show(self, prefix: str) -> None: + def show(self, prefix: str, default: str=None) -> None: """Shows the palette with the passed prefix""" self.update_idletasks() @@ -167,3 +167,6 @@ def show(self, prefix: str) -> None: self.focus_set() self.searchbar.focus() self.searchbar.add_prefix(prefix) + + if default: + self.searchbar.set_search_term(default) diff --git a/biscuit/core/components/floating/palette/searchbar.py b/biscuit/core/components/floating/palette/searchbar.py index e15d4c3c..f652c83b 100644 --- a/biscuit/core/components/floating/palette/searchbar.py +++ b/biscuit/core/components/floating/palette/searchbar.py @@ -42,8 +42,14 @@ def focus(self) -> None: self.search_bar.focus() def add_prefix(self, prefix: str) -> None: + self.prefix = prefix self.text_variable.set(prefix + " " if prefix else "") self.search_bar.icursor(tk.END) + + def set_search_term(self, term: str) -> None: + self.text_variable.set(self.search_bar.get() + term) + self.search_bar.select_range(len(self.prefix), tk.END) + self.search_bar.icursor(tk.END) def get_search_term(self) -> str: return self.search_bar.get().lower() diff --git a/biscuit/core/components/views/sidebar/explorer/directorytree.py b/biscuit/core/components/views/sidebar/explorer/directorytree.py index 19fcd6f0..cf256410 100644 --- a/biscuit/core/components/views/sidebar/explorer/directorytree.py +++ b/biscuit/core/components/views/sidebar/explorer/directorytree.py @@ -117,24 +117,27 @@ def update_treeview(self, parent_path, parent="") -> None: # sort: directories first, then files (alphabetic order) entries.sort(key=lambda x: (not os.path.isdir(x[1]), x[0])) - for name, path in entries: - if os.path.isdir(path): - if name in self.ignore_dirs: - continue - - node = self.tree.insert(parent, "end", text=f" {name}", values=[path, 'directory'], image='foldericon', open=False) - self.nodes[os.path.abspath(path)] = node - self.tree.insert(node, "end", text="loading...") - - # recursive mode loading (not good for large projects) - #self.update_treeview(path, node) - else: - if name.split(".")[-1] in self.ignore_exts: - continue - - #TODO check filetype and get matching icon, cases - node = self.tree.insert(parent, "end", text=f" {name}", values=[path, 'file'], image='document') - self.nodes[os.path.abspath(path)] = node + try: + for name, path in entries: + if os.path.isdir(path): + if name in self.ignore_dirs: + continue + + node = self.tree.insert(parent, "end", text=f" {name}", values=[path, 'directory'], image='foldericon', open=False) + self.nodes[os.path.abspath(path)] = node + self.tree.insert(node, "end", text="loading...") + + # recursive mode loading (not good for large projects) + #self.update_treeview(path, node) + else: + if name.split(".")[-1] in self.ignore_exts: + continue + + #TODO check filetype and get matching icon, cases + node = self.tree.insert(parent, "end", text=f" {name}", values=[path, 'file'], image='document') + self.nodes[os.path.abspath(path)] = node + except Exception as e: + self.base.logger.error(f"Error updating treeview: {e}") def selected_directory(self) -> str: return (self.tree.selected_path().strip() if self.tree.selected_type() != 'file' else self.tree.selected_parent_path().strip()) or self.path diff --git a/biscuit/core/events.py b/biscuit/core/events.py index 5c385e9c..b1e732e2 100644 --- a/biscuit/core/events.py +++ b/biscuit/core/events.py @@ -160,6 +160,9 @@ def register_game(self, game: BaseGame) -> None: def register_langserver(self, language: str, command: str) -> None: self.language_server_manager.register_langserver(language, command) + + def register_run_command(self, language: str, command: str) -> None: + self.exec_manager.register_command(language, command) def open_in_new_window(self, dir: str) -> None: # Process(target=App(sys.argv[0], dir).run).start() diff --git a/biscuit/core/exec.py b/biscuit/core/exec.py index f6dc1258..51e9b800 100644 --- a/biscuit/core/exec.py +++ b/biscuit/core/exec.py @@ -15,7 +15,8 @@ def register_command(self, language: str, command: str) -> None: self.commands[language] = command def run_command(self, editor: BaseEditor) -> None: - self.base.terminalmanager.run_command(editor.run_command) + self.base.terminalmanager.run_command(editor.run_command_value) + self.base.terminalmanager.active_terminal.enter() def get_command(self, editor: BaseEditor) -> str: if c := self.commands.get(editor.language, None): diff --git a/biscuit/core/gui.py b/biscuit/core/gui.py index ce915af1..1f510489 100644 --- a/biscuit/core/gui.py +++ b/biscuit/core/gui.py @@ -103,6 +103,7 @@ def late_setup(self) -> None: self.binder.late_bind_all() self.editorsmanager.add_default_editors() + self.editorsmanager.generate_actionsets() self.settings.late_setup() self.history.generate_actionsets() diff --git a/biscuit/core/layout/base/content/editors/__init__.py b/biscuit/core/layout/base/content/editors/__init__.py index a9d245ce..9d079bd0 100644 --- a/biscuit/core/layout/base/content/editors/__init__.py +++ b/biscuit/core/layout/base/content/editors/__init__.py @@ -43,8 +43,6 @@ def __init__(self, master: ContentPane, *args, **kwargs) -> None: self.emptytab.grid(column=0, row=1, sticky=tk.NSEW) self.default_editors: List[Editor] = [Welcome(self)] - self.actionset = ActionSet("Switch to active editors", "active:", []) - self.base.palette.register_actionset(self.get_active_actionset) def is_empty(self) -> bool: "Checks if the editor is empty" @@ -59,6 +57,21 @@ def get_active_actionset(self) -> ActionSet: self.actionset.update([(editor.filename, editor) for editor in self.active_editors]) return self.actionset + def generate_actionsets(self) -> None: + self.actionset = ActionSet("Switch to active editors", "active:", []) + self.base.palette.register_actionset(self.get_active_actionset) + + self.base.palette.register_actionset( + lambda: ActionSet( + "Configure Run Command", "runconf:", + pinned=[ + [ + "Run: {}", + lambda command=None, e=self.base.editorsmanager.active_editor: e.content.set_run_command(command) + if command else print("Command can't be empty!") + ]] + )) + def add_default_editors(self) -> None: "Adds all default editors" self.add_editors(self.default_editors) diff --git a/biscuit/core/utils/events.py b/biscuit/core/utils/events.py index 6f2f8faf..59acbd24 100644 --- a/biscuit/core/utils/events.py +++ b/biscuit/core/utils/events.py @@ -265,6 +265,9 @@ def change_git_branch(self, *_) -> None: def change_time_format(self, *_) -> None: self.base.palette.show('time:') + def show_run_config_palette(self, command) -> None: + self.base.palette.show('runconf:', command) + def show_file_search_palette(self, *_) -> None: self.base.palette.show("")