From 2eccabeaa5e195d0bfc5dbc05769e055250e8b24 Mon Sep 17 00:00:00 2001 From: spy Date: Tue, 15 Mar 2022 22:12:52 +0000 Subject: [PATCH] Begin to read in files at startup --- .gitignore | 1 + core/buffer.py | 9 ++++ core/files.py | 4 ++ core/statusbar.py | 4 +- core/utils.py | 18 ++++---- lambda | 94 +---------------------------------------- lambda.py | 104 ++++++++++++++++++++++++++++++++++++++++++++++ modes/normal.py | 5 +++ 8 files changed, 136 insertions(+), 103 deletions(-) create mode 100644 core/files.py create mode 100755 lambda.py diff --git a/.gitignore b/.gitignore index ea8c4bf..3a8cabc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +.idea diff --git a/core/buffer.py b/core/buffer.py index e69de29..8646d9c 100644 --- a/core/buffer.py +++ b/core/buffer.py @@ -0,0 +1,9 @@ +import curses + + +def write_buffer(stdscr, data): + count = 0 + for line in data["buffer_list"]: + str_line = "".join(line) + stdscr.addstr(count, len(data["info_bar"][0]), str_line + (" " * (len(line) - 1)), curses.color_pair(1)) + count += 1 diff --git a/core/files.py b/core/files.py new file mode 100644 index 0000000..599a755 --- /dev/null +++ b/core/files.py @@ -0,0 +1,4 @@ +def open_file(file): + with open(file) as f: + lines = f.readlines() + return lines diff --git a/core/statusbar.py b/core/statusbar.py index 7101e5e..53e1da1 100644 --- a/core/statusbar.py +++ b/core/statusbar.py @@ -9,7 +9,7 @@ def themes(data): # Add spaces before each part icon = f" {data['icon']}" mode = f" {data['mode'].upper()}" - file = f" {data['file']}" + file = f" {data['buffer_name']}" else: # The theme colors @@ -18,7 +18,7 @@ def themes(data): # Add spaces on either end icon = f" {data['icon']} " mode = f" {data['mode'].upper()} " - file = f" {data['file']} " + file = f" {data['buffer_name']} " return colors, icon, mode, file diff --git a/core/utils.py b/core/utils.py index 8c604c6..5470687 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,17 +1,17 @@ from sys import exit -from core import cursor import curses def goodbye(stdscr, data): # The prompt message - prompt = "Really quit lambda? (y or n): " + saved = "All changes are saved." + prompt = "Really quit? (y or n): " # Clear the bottom line - stdscr.addstr(data["height"]-1, 0, " " * (data["width"] - 1), curses.color_pair(1)) - + stdscr.addstr(data["height"] - 1, 0, " " * (data["width"] - 1), curses.color_pair(1)) + # Print the prompt - stdscr.addstr(data["height"]-1, 0, prompt, curses.color_pair(11)) + stdscr.addstr(data["height"] - 1, 0, prompt, curses.color_pair(11)) # Wait for and capture a key press from the user key = stdscr.getch() @@ -21,17 +21,17 @@ def goodbye(stdscr, data): exit() # Clear the bottom line again - stdscr.addstr(data["height"]-1, 0, " " * (data["width"] - 1), curses.color_pair(1)) + stdscr.addstr(data["height"] - 1, 0, " " * (data["width"] - 1), curses.color_pair(1)) def error(stdscr, data, error_msg): # Print the error message to the bottom line error_msg = f"ERROR: {error_msg}" - stdscr.addstr(data["height"]-1, 0, error_msg, curses.color_pair(3)) - stdscr.addstr(data["height"]-1, len(error_msg) + 1, "(press any key) ", curses.color_pair(1)) + stdscr.addstr(data["height"] - 1, 0, error_msg, curses.color_pair(3)) + stdscr.addstr(data["height"] - 1, len(error_msg) + 1, "(press any key) ", curses.color_pair(1)) # Wait for a key to be pressed stdscr.getch() # Clear the bottom line - stdscr.addstr(data["height"]-1, 0, " " * (data["width"] - 1), curses.color_pair(1)) \ No newline at end of file + stdscr.addstr(data["height"] - 1, 0, " " * (data["width"] - 1), curses.color_pair(1)) diff --git a/lambda b/lambda index f7c2b09..6f03d04 100755 --- a/lambda +++ b/lambda @@ -1,93 +1,3 @@ -#!/usr/bin/python -from core import colors, cursor, mode -import os -import curses -import argparse +#!/bin/sh - -def start_screen(stdscr): - # Get window height and width - height, width = stdscr.getmaxyx() - - # Startup text - title = "λ Lambda" - subtext = [ - "Next generation hackable text editor for nerds", - "", - "Type :h to open the README.md document", - "Type :o to open a file and edit", - "Type :q or to quit lambda" - ] - - # Centering calculations - start_x_title = int((width // 2) - (len(title) // 2) - len(title) % 2) - start_y = int((height // 2) - 2) - - # Rendering title - stdscr.addstr(start_y, start_x_title, title, curses.color_pair(7) | curses.A_BOLD) - - # Print the subtext - for text in subtext: - start_y += 1 - start_x = int((width // 2) - (len(text) // 2) - len(text) % 2) - stdscr.addstr(start_y, start_x, text) - - -def start(stdscr, file): - # Initialise data before starting - data = { - "cursor_y": 0, - "cursor_x": 0, - "height": 0, - "width": 0, - "mode": "normal", - "icon": "λ", - "file": file, - "statusbar_theme": "filled" - } - - # Initialise colors - colors.init_colors() - - # Change the cursor shape - cursor.cursor_mode("block") - - # Start the screen - start_screen(stdscr) - - # Main loop - while True: - # Get the height and width of the screen - data["height"], data["width"] = stdscr.getmaxyx() - - # Activate the next mode - data = mode.activate(stdscr, data) - - # Refresh and clear the screen - stdscr.refresh() - stdscr.clear() - - -def main(): - parser = argparse.ArgumentParser(description="Process some integers.") - parser.add_argument("file", metavar="file", type=str, nargs="?", - help="File to open") - - args = parser.parse_args() - # Check the file name - if args.file: - file = args.file - - else: - file = "[No Name]" - - # Change the escape delay to 25ms - # Fixes an issue where esc takes too long to press - os.environ.setdefault("ESCDELAY", "25") - - # Initialise the screen - curses.wrapper(start, file) - - -if __name__ == "__main__": - main() +python3 ./lambda.py $@ diff --git a/lambda.py b/lambda.py new file mode 100755 index 0000000..fabe9ba --- /dev/null +++ b/lambda.py @@ -0,0 +1,104 @@ +from core import colors, cursor, mode, files, buffer +import os +import curses +import argparse + + +def start_screen(stdscr): + # Get window height and width + height, width = stdscr.getmaxyx() + + # Startup text + title = "λ Lambda" + subtext = [ + "Next generation hackable text editor for nerds", + "", + "Type :h to open the README.md document", + "Type :o to open a file and edit", + "Type :q or to quit lambda.py" + ] + + # Centering calculations + start_x_title = int((width // 2) - (len(title) // 2) - len(title) % 2) + start_y = int((height // 2) - 2) + + # Rendering title + stdscr.addstr(start_y, start_x_title, title, curses.color_pair(7) | curses.A_BOLD) + + # Print the subtext + for text in subtext: + start_y += 1 + start_x = int((width // 2) - (len(text) // 2) - len(text) % 2) + stdscr.addstr(start_y, start_x, text) + + +def start(stdscr, buffer_name, buffer_list): + # Initialise data before starting + data = { + "cursor_y": 0, + "cursor_x": 0, + "height": 0, + "width": 0, + "mode": "normal", + "icon": "λ", + "info_bar": [" "], + "buffer_name": buffer_name, + "buffer_list": buffer_list, + "statusbar_theme": "filled" + } + + # Initialise colors + colors.init_colors() + + # Change the cursor shape + cursor.cursor_mode("block") + + # Start the screen + if data["buffer_name"] == "[No Name]": + start_screen(stdscr) + + # Main loop + while True: + # Get the height and width of the screen + data["height"], data["width"] = stdscr.getmaxyx() + + # Write the buffer to the screen + buffer.write_buffer(stdscr, data) + + # Activate the next mode + data = mode.activate(stdscr, data) + + # Refresh and clear the screen + stdscr.refresh() + stdscr.clear() + + +def main(): + parser = argparse.ArgumentParser(description="Process some integers.") + parser.add_argument("file", metavar="file", type=str, nargs="?", + help="File to open") + + args = parser.parse_args() + # Check if a file name has been inputted + if args.file: + buffer_name = args.file + buffer_list = files.open_file(buffer_name) + + # Convert each line into a list of lists with each element of the sublist representing one character + for index, line in enumerate(buffer_list): + buffer_list[index] = list(line) + + else: + buffer_name = "[No Name]" + buffer_list = [[""]] + + # Change the escape delay to 25ms + # Fixes an issue where esc takes too long to press + os.environ.setdefault("ESCDELAY", "25") + + # Initialise the screen + curses.wrapper(start, buffer_name, buffer_list) + + +if __name__ == "__main__": + main() diff --git a/modes/normal.py b/modes/normal.py index cd90104..0bfedbc 100644 --- a/modes/normal.py +++ b/modes/normal.py @@ -22,6 +22,11 @@ def execute(data, key): # Exit normal mode and enter insert mode data["mode"] = "insert" + elif key == ord("I"): + # Exit normal mode and enter insert mode + data["cursor_x"] += 1 + data["mode"] = "insert" + elif key in (ord(":"), ord(";")): # Exit normal mode and enter command mode data["mode"] = "command"