✨ Fixed cursor & width, added statusbar themes & more
This commit is contained in:
parent
0d06c65a13
commit
b5553440fc
@ -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
|
||||||
|
|
||||||
|
@ -7,12 +7,46 @@ 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)
|
||||||
|
|
||||||
|
# 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):
|
for count, component in enumerate(self.components):
|
||||||
instance.screen.addstr(instance.height - 2, x, component,
|
instance.screen.addstr(instance.height - 2, x, component,
|
||||||
curses.color_pair(self.colors[count]) | curses.A_BOLD)
|
curses.color_pair(self.colors[count]) | curses.A_BOLD)
|
||||||
@ -20,16 +54,17 @@ class StatusBar:
|
|||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
@ -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])
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
|
||||||
|
8
main.py
8
main.py
@ -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
|
||||||
|
@ -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}'")
|
||||||
|
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user