Fixed cursor & width, added statusbar themes & more

This commit is contained in:
Maddie H 2022-04-15 13:44:24 +01:00
parent 0d06c65a13
commit b5553440fc
9 changed files with 88 additions and 42 deletions

View File

@ -41,6 +41,9 @@ def open_file(file_name):
if lines[-1].endswith("\n") or not len(lines): if lines[-1].endswith("\n") or not len(lines):
lines.append("") lines.append("")
# Remove the newlines
lines = [line.rstrip("\n") for line in lines]
# Return the list of lines # Return the list of lines
return lines return lines

View File

@ -7,29 +7,64 @@ class StatusBar:
self.mode = instance.mode.upper() self.mode = instance.mode.upper()
self.file = instance.buffer.name or "[No Name]" self.file = instance.buffer.name or "[No Name]"
self.icon = instance.config["icon"] or "λ" 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] self.components = [self.icon, self.mode, self.file]
def render(self, instance): def render(self, instance):
x = 1 # Clear the status bar
utils.clear(instance, instance.height - 2, 0) utils.clear(instance, instance.height - 2, 0)
for count, component in enumerate(self.components):
instance.screen.addstr(instance.height - 2, x, component, # Update variables
curses.color_pair(self.colors[count]) | curses.A_BOLD) self.update(instance)
x += len(component) + 1
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: class Components:
def __init__(self, components: dict = None): def __init__(self, instance, components: dict = None):
self.components = components or { self.components = components or {
"left": [" "], "left": [" "],
"bottom": [StatusBar], "bottom": [StatusBar(instance)],
} }
curses.endwin()
@staticmethod @staticmethod
def get_component_width(component: list) -> int: 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): def render(self, instance):
for component in self.components["bottom"]: for component in self.components["bottom"]:
component(instance).render(instance) component.render(instance)

View File

@ -1,4 +1,3 @@
from core import utils
import curses import curses
@ -16,7 +15,6 @@ def mode(to_mode: str):
curses.curs_set(1) curses.curs_set(1)
# TODO
def push(instance, direction: (int, str)): def push(instance, direction: (int, str)):
if direction in (0, "up", "north"): if direction in (0, "up", "north"):
# If the cursor isn't at the top of the screen # 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: if instance.raw_cursor[0] == 0 and instance.cursor[0] == instance.offset[0] and instance.cursor[0] != 0:
instance.offset[0] -= 1 instance.offset[0] -= 1
elif direction in (1, "right", "east"):
instance.raw_cursor[1] += 1
elif direction in (2, "down", "south"): elif direction in (2, "down", "south"):
if instance.raw_cursor[0] == instance.safe_height and instance.cursor[0] != len(instance.buffer.data) - 1: if instance.raw_cursor[0] == instance.safe_height and instance.cursor[0] != len(instance.buffer.data) - 1:
instance.offset[0] += 1 instance.offset[0] += 1
@ -40,14 +35,18 @@ def push(instance, direction: (int, str)):
# Move the cursor down # Move the cursor down
instance.raw_cursor[0] += 1 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"): elif direction in (3, "left", "west"):
if instance.raw_cursor[1] > 0: # Move the cursor one to the left
instance.raw_cursor[1] -= 1 instance.raw_cursor[1] -= 1
def check(instance, cursor: list) -> list: def check(instance, cursor: list) -> list:
# Prevent the cursor from going outside the buffer # 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 # Prevent any negative values
cursor[0] = max(0, cursor[0]) cursor[0] = max(0, cursor[0])

View File

@ -10,14 +10,17 @@ def activate(instance, mode):
if mode == "command": if mode == "command":
# Activate command mode # Activate command mode
instance.components.components["bottom"][0].colors[1] = 5
command.activate(instance) command.activate(instance)
elif mode == "insert": elif mode == "insert":
# Activate insert mode # Activate insert mode
instance.components.components["bottom"][0].colors[1] = 9
insert.activate() insert.activate()
elif mode == "normal": elif mode == "normal":
# Activate normal mode # Activate normal mode
instance.components.components["bottom"][0].colors[1] = 5
normal.activate() normal.activate()

View File

@ -67,6 +67,9 @@ def prompt(instance, message: str, color: int = 1) -> (list, None):
# Initialise the input list # Initialise the input list
inp = [] inp = []
# Write whitespace over characters to refresh it
clear(instance, instance.height - 1, len(message) + len(inp) - 1)
# Write the message to the screen # Write the message to the screen
instance.screen.addstr(instance.height - 1, 0, message, curses.color_pair(color)) instance.screen.addstr(instance.height - 1, 0, message, curses.color_pair(color))

View File

@ -8,11 +8,10 @@ from core.components import Components
class Lambda: class Lambda:
def __init__(self, buffer: Buffer, config: dict = None): def __init__(self, buffer: Buffer = None, config: dict = None):
self.screen = curses.initscr() self.screen = curses.initscr()
self.components = Components()
self.config = config or {"icon": "λ"} self.config = config or {"icon": "λ"}
self.buffer = buffer self.buffer = buffer or [""]
self.mode = "normal" self.mode = "normal"
self.cursor = [0, 0] self.cursor = [0, 0]
self.raw_cursor = [0, 0] self.raw_cursor = [0, 0]
@ -21,6 +20,7 @@ class Lambda:
self.width = 0 self.width = 0
self.safe_height = 0 self.safe_height = 0
self.safe_width = 0 self.safe_width = 0
self.components = Components(self)
def update_dimensions(self): def update_dimensions(self):
# Calculate the entire height and width of the terminal # 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 self.safe_width = self.width - self.components.get_component_width(self.components.components["left"]) - 1
def refresh(self): 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] 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 # Update the dimensions of the terminal

View File

@ -1,28 +1,26 @@
from core import utils from core import utils
def execute(instance, commands): def execute(instance, commands: list):
# Only if commands are given # Only if commands are given
if commands: if commands:
# Check each command in the list of commands # Check each command in the list of commands
for command in commands: for command in commands:
# Write if command == "w": # Write
if command == "w":
# Write to the file # Write to the file
pass pass
elif command == "d": if command == "d": # Debug
# Load a prompt with debug info # Create the debug prompt
utils.prompt(instance, f"Cursor: {instance.cursor} | Raw: {instance.raw_cursor} | Len: {len(instance.buffer.data)}") utils.prompt(instance, f"*Whawt awe uwu doing tuwu me mastew?* "
utils.prompt(instance, f"{len(instance.buffer.data[6])}") f"Cursor: {instance.cursor} Raw: {instance.raw_cursor} "
f"Len: {len(instance.buffer.data)}")
# Quit elif command == "q": # Quit
elif command == "q": # Create a goodbye prompt
# Load a goodbye prompt
utils.goodbye(instance) utils.goodbye(instance)
# Unknown command else: # Invalid command
else:
utils.error(instance, f"invalid command: '{command}'") utils.error(instance, f"invalid command: '{command}'")

View File

@ -2,8 +2,7 @@ from core import cursors, modes
def execute(instance, key): def execute(instance, key):
# Enter key if key == 27: # Enter
if key == 27:
# Switch to normal mode # Switch to normal mode
modes.activate(instance, "normal") modes.activate(instance, "normal")

View File

@ -1,20 +1,26 @@
from core import cursors, modes import curses
from core import cursors, modes, utils
def execute(instance, key): 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 # Move the cursor down
cursors.push(instance, "down") cursors.push(instance, "down")
elif key == ord("k"): elif key in (ord("k"), curses.KEY_UP):
# Move the cursor up # Move the cursor up
cursors.push(instance, "up") cursors.push(instance, "up")
elif key == ord("l"): elif key in (ord("l"), curses.KEY_RIGHT):
# Move the cursor right # Move the cursor right
cursors.push(instance, "right") cursors.push(instance, "right")
elif key == ord("h"): elif key in (ord("h"), curses.KEY_LEFT):
# Move the cursor left # Move the cursor left
cursors.push(instance, "left") cursors.push(instance, "left")