diff --git a/core/buffers.py b/core/buffers.py index 0fef9c0..59ab4e8 100644 --- a/core/buffers.py +++ b/core/buffers.py @@ -41,6 +41,9 @@ def open_file(file_name): if lines[-1].endswith("\n") or not len(lines): lines.append("") + # Remove the newlines + lines = [line.rstrip("\n") for line in lines] + # Return the list of lines return lines diff --git a/core/components.py b/core/components.py index 007811d..810acae 100644 --- a/core/components.py +++ b/core/components.py @@ -7,29 +7,64 @@ class StatusBar: self.mode = instance.mode.upper() self.file = instance.buffer.name or "[No Name]" self.icon = instance.config["icon"] or "λ" - self.colors = (7, 5, 13) + self.theme = "inverted" + self.colors = [7, 5, 13] + self.components = [self.icon, self.mode, self.file] + + def update(self, instance): + self.mode = instance.mode.upper() self.components = [self.icon, self.mode, self.file] def render(self, instance): - x = 1 + # Clear the status bar utils.clear(instance, instance.height - 2, 0) - for count, component in enumerate(self.components): - instance.screen.addstr(instance.height - 2, x, component, - curses.color_pair(self.colors[count]) | curses.A_BOLD) - x += len(component) + 1 + + # Update variables + self.update(instance) + + if self.theme == "inverted": + # Initialise temporary colors for inverted theme + colors = [] + + # Add 1 to each color temporarily + for color in self.colors: + colors.append(color + 1) + + # Initialise the x position for each component + x = 0 + + for count, component in enumerate(self.components): + component = " " + component + " " + instance.screen.addstr(instance.height - 2, x, component, + curses.color_pair(colors[count]) | curses.A_BOLD) + x += len(component) + + # Add a space at the end of the status bar + instance.screen.addstr(instance.height - 2, x, " " * (instance.width - x), + curses.color_pair(2)) + else: + # Initialise the x position for each component + x = 1 + + # Render each component + for count, component in enumerate(self.components): + instance.screen.addstr(instance.height - 2, x, component, + curses.color_pair(self.colors[count]) | curses.A_BOLD) + x += len(component) + 1 class Components: - def __init__(self, components: dict = None): + def __init__(self, instance, components: dict = None): self.components = components or { - "left": [" "], - "bottom": [StatusBar], + "left": [" "], + "bottom": [StatusBar(instance)], } + curses.endwin() @staticmethod def get_component_width(component: list) -> int: - return sum(len(max(sub_components)) for sub_components in component if max(sub_components)) + return len(max(component)) def render(self, instance): for component in self.components["bottom"]: - component(instance).render(instance) + component.render(instance) diff --git a/core/cursors.py b/core/cursors.py index d38dea1..c76079f 100644 --- a/core/cursors.py +++ b/core/cursors.py @@ -1,4 +1,3 @@ -from core import utils import curses @@ -16,7 +15,6 @@ def mode(to_mode: str): curses.curs_set(1) -# TODO def push(instance, direction: (int, str)): if direction in (0, "up", "north"): # If the cursor isn't at the top of the screen @@ -28,9 +26,6 @@ def push(instance, direction: (int, str)): if instance.raw_cursor[0] == 0 and instance.cursor[0] == instance.offset[0] and instance.cursor[0] != 0: instance.offset[0] -= 1 - elif direction in (1, "right", "east"): - instance.raw_cursor[1] += 1 - elif direction in (2, "down", "south"): if instance.raw_cursor[0] == instance.safe_height and instance.cursor[0] != len(instance.buffer.data) - 1: instance.offset[0] += 1 @@ -40,14 +35,18 @@ def push(instance, direction: (int, str)): # Move the cursor down instance.raw_cursor[0] += 1 + elif direction in (1, "right", "east"): + # Move the cursor one to the right + instance.raw_cursor[1] += 1 + elif direction in (3, "left", "west"): - if instance.raw_cursor[1] > 0: - instance.raw_cursor[1] -= 1 + # Move the cursor one to the left + instance.raw_cursor[1] -= 1 def check(instance, cursor: list) -> list: # Prevent the cursor from going outside the buffer - cursor[1] = min(len(instance.buffer.data[instance.cursor[0]]) - 2, cursor[1]) + cursor[1] = min(len(instance.buffer.data[instance.cursor[0]]) - 1, cursor[1]) # Prevent any negative values cursor[0] = max(0, cursor[0]) diff --git a/core/modes.py b/core/modes.py index 43f7279..e318da8 100644 --- a/core/modes.py +++ b/core/modes.py @@ -10,14 +10,17 @@ def activate(instance, mode): if mode == "command": # Activate command mode + instance.components.components["bottom"][0].colors[1] = 5 command.activate(instance) elif mode == "insert": # Activate insert mode + instance.components.components["bottom"][0].colors[1] = 9 insert.activate() elif mode == "normal": # Activate normal mode + instance.components.components["bottom"][0].colors[1] = 5 normal.activate() diff --git a/core/utils.py b/core/utils.py index e913205..2bbd43e 100644 --- a/core/utils.py +++ b/core/utils.py @@ -67,6 +67,9 @@ def prompt(instance, message: str, color: int = 1) -> (list, None): # Initialise the input list inp = [] + # Write whitespace over characters to refresh it + clear(instance, instance.height - 1, len(message) + len(inp) - 1) + # Write the message to the screen instance.screen.addstr(instance.height - 1, 0, message, curses.color_pair(color)) diff --git a/main.py b/main.py index d21255a..d114803 100644 --- a/main.py +++ b/main.py @@ -8,11 +8,10 @@ from core.components import Components class Lambda: - def __init__(self, buffer: Buffer, config: dict = None): + def __init__(self, buffer: Buffer = None, config: dict = None): self.screen = curses.initscr() - self.components = Components() self.config = config or {"icon": "λ"} - self.buffer = buffer + self.buffer = buffer or [""] self.mode = "normal" self.cursor = [0, 0] self.raw_cursor = [0, 0] @@ -21,6 +20,7 @@ class Lambda: self.width = 0 self.safe_height = 0 self.safe_width = 0 + self.components = Components(self) def update_dimensions(self): # Calculate the entire height and width of the terminal @@ -31,7 +31,7 @@ class Lambda: self.safe_width = self.width - self.components.get_component_width(self.components.components["left"]) - 1 def refresh(self): - # Calculate the real cursor position + # Calculate the cursor position in the file self.cursor[0], self.cursor[1] = self.raw_cursor[0] + self.offset[0], self.raw_cursor[1] + self.offset[1] # Update the dimensions of the terminal diff --git a/mode/command.py b/mode/command.py index 9500aca..b67ca1f 100644 --- a/mode/command.py +++ b/mode/command.py @@ -1,28 +1,26 @@ from core import utils -def execute(instance, commands): +def execute(instance, commands: list): # Only if commands are given if commands: # Check each command in the list of commands for command in commands: - # Write - if command == "w": + if command == "w": # Write # Write to the file pass - elif command == "d": - # Load a prompt with debug info - utils.prompt(instance, f"Cursor: {instance.cursor} | Raw: {instance.raw_cursor} | Len: {len(instance.buffer.data)}") - utils.prompt(instance, f"{len(instance.buffer.data[6])}") + if command == "d": # Debug + # Create the debug prompt + utils.prompt(instance, f"*Whawt awe uwu doing tuwu me mastew?* " + f"Cursor: {instance.cursor} Raw: {instance.raw_cursor} " + f"Len: {len(instance.buffer.data)}") - # Quit - elif command == "q": - # Load a goodbye prompt + elif command == "q": # Quit + # Create a goodbye prompt utils.goodbye(instance) - # Unknown command - else: + else: # Invalid command utils.error(instance, f"invalid command: '{command}'") diff --git a/mode/insert.py b/mode/insert.py index 18f9f8f..8e009a8 100644 --- a/mode/insert.py +++ b/mode/insert.py @@ -2,8 +2,7 @@ from core import cursors, modes def execute(instance, key): - # Enter key - if key == 27: + if key == 27: # Enter # Switch to normal mode modes.activate(instance, "normal") diff --git a/mode/normal.py b/mode/normal.py index 9c19789..4bc0d44 100644 --- a/mode/normal.py +++ b/mode/normal.py @@ -1,20 +1,26 @@ -from core import cursors, modes +import curses + +from core import cursors, modes, utils def execute(instance, key): - if key == ord("j"): + if key == curses.BUTTON1_CLICKED: + # Move the cursor to the position clicked + utils.prompt(instance, str(curses.getmouse())) + + elif key in (ord("j"), curses.KEY_DOWN): # Move the cursor down cursors.push(instance, "down") - elif key == ord("k"): + elif key in (ord("k"), curses.KEY_UP): # Move the cursor up cursors.push(instance, "up") - elif key == ord("l"): + elif key in (ord("l"), curses.KEY_RIGHT): # Move the cursor right cursors.push(instance, "right") - elif key == ord("h"): + elif key in (ord("h"), curses.KEY_LEFT): # Move the cursor left cursors.push(instance, "left")