lambda-rewrite
This commit is contained in:
parent
3de29be96d
commit
e461d24d72
46
core/buffers.py
Normal file
46
core/buffers.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class Buffer:
|
||||||
|
def __init__(self, path: str, name: str = None, data: list = None):
|
||||||
|
self.path = path
|
||||||
|
self.name = name or "[No Name]"
|
||||||
|
self.data = data or [[""]]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def remove_char(string: str, index: int) -> str:
|
||||||
|
# Remove a character from a string at a given index
|
||||||
|
return string[:index] + string[index + 1:]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def insert_char(string: str, index: int, char: (str, chr)) -> str:
|
||||||
|
# Insert a character into a string at a given index
|
||||||
|
return string[:index] + char + string[index:]
|
||||||
|
|
||||||
|
|
||||||
|
def open_file(file_name):
|
||||||
|
# Open the file
|
||||||
|
with open(file_name) as f:
|
||||||
|
# Convert it into a list of lines
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
# Return the list of lines
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def load_file(file_path=None):
|
||||||
|
# Default settings for a file
|
||||||
|
file_name = "[No Name]"
|
||||||
|
file_data = [[""]]
|
||||||
|
|
||||||
|
if file_path:
|
||||||
|
# Set the file's name
|
||||||
|
file_name = os.path.basename(file_path)
|
||||||
|
|
||||||
|
# Only if the file actually exists
|
||||||
|
if os.path.exists(file_path):
|
||||||
|
# Open the file as a list of lines
|
||||||
|
file_data = open_file(file_name)
|
||||||
|
|
||||||
|
# Return a dictionary which will become all the data about the buffer
|
||||||
|
return Buffer(file_path, file_name, file_data)
|
@ -1,20 +1,51 @@
|
|||||||
import curses
|
import curses
|
||||||
|
|
||||||
|
|
||||||
|
class Codes:
|
||||||
|
# Color codes
|
||||||
|
red = '\033[91m'
|
||||||
|
green = '\033[92m'
|
||||||
|
blue = '\033[94m'
|
||||||
|
yellow = '\033[93m'
|
||||||
|
cyan = '\033[96m'
|
||||||
|
magenta = '\033[95m'
|
||||||
|
white = '\033[97m'
|
||||||
|
selected_white = '\033[47m'
|
||||||
|
selected_green = '\033[42m'
|
||||||
|
strike = '\033[9m'
|
||||||
|
italic = '\033[3m'
|
||||||
|
end = '\033[0m'
|
||||||
|
|
||||||
|
|
||||||
def init_colors():
|
def init_colors():
|
||||||
# Start colors in curses
|
# Activate color support
|
||||||
curses.start_color()
|
curses.start_color()
|
||||||
|
|
||||||
|
# Foreground: WHITE, Background: BLACK
|
||||||
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
|
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
|
||||||
|
# Foreground: BLACK, Background: WHITE
|
||||||
curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_WHITE)
|
curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_WHITE)
|
||||||
|
# Foreground: RED, Background: BLACK
|
||||||
curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK)
|
curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK)
|
||||||
|
# Foreground: BLACK, Background: RED
|
||||||
curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_RED)
|
curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_RED)
|
||||||
|
# Foreground: GREEN, Background: BLACK
|
||||||
curses.init_pair(5, curses.COLOR_GREEN, curses.COLOR_BLACK)
|
curses.init_pair(5, curses.COLOR_GREEN, curses.COLOR_BLACK)
|
||||||
|
# Foreground: BLACK, Background: GREEN
|
||||||
curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_GREEN)
|
curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_GREEN)
|
||||||
|
# Foreground: YELLOW, Background: BLACK
|
||||||
curses.init_pair(7, curses.COLOR_YELLOW, curses.COLOR_BLACK)
|
curses.init_pair(7, curses.COLOR_YELLOW, curses.COLOR_BLACK)
|
||||||
|
# Foreground: BLACK, Background: YELLOW
|
||||||
curses.init_pair(8, curses.COLOR_BLACK, curses.COLOR_YELLOW)
|
curses.init_pair(8, curses.COLOR_BLACK, curses.COLOR_YELLOW)
|
||||||
|
# Foreground: CYAN, Background: BLACK
|
||||||
curses.init_pair(9, curses.COLOR_CYAN, curses.COLOR_BLACK)
|
curses.init_pair(9, curses.COLOR_CYAN, curses.COLOR_BLACK)
|
||||||
|
# Foreground: BLACK, Background: CYAN
|
||||||
curses.init_pair(10, curses.COLOR_BLACK, curses.COLOR_CYAN)
|
curses.init_pair(10, curses.COLOR_BLACK, curses.COLOR_CYAN)
|
||||||
|
# Foreground: BLUE, Background: BLACK
|
||||||
curses.init_pair(11, curses.COLOR_BLUE, curses.COLOR_BLACK)
|
curses.init_pair(11, curses.COLOR_BLUE, curses.COLOR_BLACK)
|
||||||
|
# Foreground: BLACK, Background: BLUE
|
||||||
curses.init_pair(12, curses.COLOR_BLACK, curses.COLOR_BLUE)
|
curses.init_pair(12, curses.COLOR_BLACK, curses.COLOR_BLUE)
|
||||||
|
# Foreground: MAGENTA, Background: BLACK
|
||||||
curses.init_pair(13, curses.COLOR_MAGENTA, curses.COLOR_BLACK)
|
curses.init_pair(13, curses.COLOR_MAGENTA, curses.COLOR_BLACK)
|
||||||
|
# Foreground: BLACK, Background: MAGENTA
|
||||||
curses.init_pair(14, curses.COLOR_BLACK, curses.COLOR_MAGENTA)
|
curses.init_pair(14, curses.COLOR_BLACK, curses.COLOR_MAGENTA)
|
||||||
|
31
core/components.py
Normal file
31
core/components.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
from core import utils
|
||||||
|
import curses
|
||||||
|
|
||||||
|
|
||||||
|
class StatusBar:
|
||||||
|
def __init__(self, instance):
|
||||||
|
self.instance = instance
|
||||||
|
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.components = [self.icon, self.mode, self.file]
|
||||||
|
|
||||||
|
def render(self):
|
||||||
|
x = 1
|
||||||
|
utils.clear(self.instance, self.instance.height - 2, 0)
|
||||||
|
for count, component in enumerate(self.components):
|
||||||
|
self.instance.screen.addstr(self.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):
|
||||||
|
self.components = components or {
|
||||||
|
"bottom": [StatusBar],
|
||||||
|
}
|
||||||
|
|
||||||
|
def render(self, instance):
|
||||||
|
for component in self.components["bottom"]:
|
||||||
|
component(instance).render()
|
40
core/cursors.py
Normal file
40
core/cursors.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import curses
|
||||||
|
|
||||||
|
|
||||||
|
def cursor_mode(mode):
|
||||||
|
if mode == "block":
|
||||||
|
print("\033[2 q")
|
||||||
|
|
||||||
|
elif mode == "line":
|
||||||
|
print("\033[6 q")
|
||||||
|
|
||||||
|
elif mode == "hidden":
|
||||||
|
curses.curs_set(0)
|
||||||
|
|
||||||
|
elif mode == "visible":
|
||||||
|
curses.curs_set(1)
|
||||||
|
|
||||||
|
|
||||||
|
def cursor_push(cursor: list, direction: (int, str)) -> list:
|
||||||
|
if direction in (0, "up", "north"):
|
||||||
|
# Decrease the y position
|
||||||
|
cursor[0] -= 1
|
||||||
|
|
||||||
|
elif direction in (1, "right", "east"):
|
||||||
|
# Increase the x position
|
||||||
|
cursor[1] += 1
|
||||||
|
|
||||||
|
elif direction in (2, "down", "south"):
|
||||||
|
# Increase the y position
|
||||||
|
cursor[0] += 1
|
||||||
|
|
||||||
|
elif direction in (3, "left", "west"):
|
||||||
|
# Decrease the x position
|
||||||
|
cursor[1] -= 1
|
||||||
|
|
||||||
|
return cursor
|
||||||
|
|
||||||
|
|
||||||
|
def cursor_move(screen, cursor: list):
|
||||||
|
# Moves the cursor to anywhere on the screen
|
||||||
|
screen.move(cursor[0], cursor[1])
|
33
core/modes.py
Normal file
33
core/modes.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
from mode import normal, insert, command
|
||||||
|
|
||||||
|
|
||||||
|
def activate(instance, mode) -> object:
|
||||||
|
# Visibly update the mode
|
||||||
|
instance.mode = mode
|
||||||
|
instance.update()
|
||||||
|
|
||||||
|
if mode == "command":
|
||||||
|
instance = command.activate(instance)
|
||||||
|
|
||||||
|
elif mode == "insert":
|
||||||
|
instance = insert.activate(instance)
|
||||||
|
|
||||||
|
elif mode == "normal":
|
||||||
|
instance = normal.activate(instance)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
def handle_key(instance, key):
|
||||||
|
if instance.mode == "normal":
|
||||||
|
instance = normal.execute(instance, key)
|
||||||
|
|
||||||
|
# Insert mode - inserting text to the buffer
|
||||||
|
elif instance.mode == "insert":
|
||||||
|
instance = insert.execute(instance, key)
|
||||||
|
|
||||||
|
# Command mode - extra commands for lambda
|
||||||
|
elif instance.mode == "command":
|
||||||
|
instance = command.activate(instance)
|
||||||
|
|
||||||
|
return instance
|
130
core/utils.py
130
core/utils.py
@ -1,51 +1,109 @@
|
|||||||
from sys import exit
|
|
||||||
import curses
|
import curses
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def refresh_window_size(screen, data):
|
def clear(instance, y: int, x: int):
|
||||||
# Get the height and width of the screen
|
# Clear the line at the screen at position y, x
|
||||||
data["height"], data["width"] = screen.getmaxyx()
|
instance.screen.insstr(y, x, " " * (instance.width - x))
|
||||||
|
|
||||||
# Return the data as changes may have been made
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def clear_line(screen, data, line):
|
def welcome(screen):
|
||||||
# Clear the specified line
|
# Get window height and width
|
||||||
screen.addstr(line, 0, " " * (data["width"] - 1), curses.color_pair(1))
|
height, width = screen.getmaxyx()
|
||||||
|
|
||||||
|
# Startup text
|
||||||
|
title = "λ Lambda"
|
||||||
|
subtext = [
|
||||||
|
"Next generation hackable text editor for nerds",
|
||||||
|
"",
|
||||||
|
"Type :h to open the README.md document",
|
||||||
|
"Type :o <file> to open a file and edit",
|
||||||
|
"Type :q or <C-c> 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
|
||||||
|
screen.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)
|
||||||
|
screen.addstr(start_y, start_x, text)
|
||||||
|
|
||||||
|
|
||||||
def prompt(screen, data, text):
|
def prompt(instance, message: str, color: int = 1) -> (list, None):
|
||||||
# Print the prompt
|
# Initialise the input list
|
||||||
screen.addstr(data["height"] - 1, 0, text, curses.color_pair(11))
|
inp = []
|
||||||
|
|
||||||
# Wait for and capture a key press from the user
|
# Write the message to the screen
|
||||||
return screen.getch()
|
instance.screen.addstr(instance.height - 1, 0, message, curses.color_pair(color))
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Wait for a keypress
|
||||||
|
key = instance.screen.getch()
|
||||||
|
|
||||||
|
# Subtracting a key (backspace)
|
||||||
|
if key in (curses.KEY_BACKSPACE, 127, '\b'):
|
||||||
|
# Write whitespace over characters to refresh it
|
||||||
|
clear(instance, instance.height - 1, 0)
|
||||||
|
|
||||||
|
if inp:
|
||||||
|
# Subtract a character from the input list
|
||||||
|
inp.pop()
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Exit the prompt without returning the input
|
||||||
|
return None
|
||||||
|
|
||||||
|
elif key == 27:
|
||||||
|
# Exit the prompt, without returning the input
|
||||||
|
return None
|
||||||
|
|
||||||
|
elif key in (curses.KEY_ENTER, ord('\n'), ord('\r'), ord(":"), ord(";")):
|
||||||
|
# Return the input list
|
||||||
|
return inp
|
||||||
|
|
||||||
|
else:
|
||||||
|
# If any other key is typed, append it
|
||||||
|
# As long as the key is in the valid list
|
||||||
|
valid = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ!"
|
||||||
|
if chr(key) in valid and len(inp) < (instance.width - 2):
|
||||||
|
inp.append(chr(key))
|
||||||
|
|
||||||
|
# Write the message to the screen
|
||||||
|
instance.screen.addstr(instance.height - 1, 0, message, curses.color_pair(color))
|
||||||
|
|
||||||
|
# Join the input together for visibility on the screen
|
||||||
|
input_text = "".join(inp)
|
||||||
|
|
||||||
|
# Write the input text to the screen
|
||||||
|
instance.screen.addstr(instance.height - 1, len(message), input_text)
|
||||||
|
|
||||||
|
|
||||||
def goodbye(screen, data):
|
def goodbye(instance):
|
||||||
# Create a goodbye prompt
|
choice = prompt(instance, "Really quit lambda? (y/n): ", 11)
|
||||||
key = prompt(screen, data, "Really quit? (y or n): ")
|
if choice and choice[0] == "y":
|
||||||
|
curses.endwin()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
# Clear the bottom line
|
else:
|
||||||
clear_line(screen, data, data["height"] - 1)
|
clear(instance, instance.height - 1, 0)
|
||||||
|
|
||||||
if key == ord("y"):
|
|
||||||
# Only exit if the key was "y", a confirmation
|
|
||||||
exit()
|
|
||||||
|
|
||||||
# Clear the bottom line again
|
|
||||||
clear_line(screen, data, data["height"] - 1)
|
|
||||||
|
|
||||||
|
|
||||||
def error(screen, data, error_msg):
|
def error(instance, message: str):
|
||||||
# Print the error message to the bottom line
|
# Parse the error message
|
||||||
error_msg = f"ERROR: {error_msg}"
|
error_message = f"ERROR: {message}"
|
||||||
screen.addstr(data["height"] - 1, 0, error_msg, curses.color_pair(3))
|
|
||||||
screen.addstr(data["height"] - 1, len(error_msg) + 1, "(press any key) ", curses.color_pair(1))
|
|
||||||
|
|
||||||
# Wait for a key to be pressed
|
# Write the entire message to the screen
|
||||||
screen.getch()
|
instance.screen.addstr(instance.height - 1, 0, f"ERROR: {message}", curses.color_pair(3))
|
||||||
|
instance.screen.addstr(instance.height - 1, len(error_message) + 1, f"(press any key)")
|
||||||
|
|
||||||
# Clear the bottom line
|
# Wait for a keypress
|
||||||
clear_line(screen, data, data["height"] - 1)
|
instance.screen.getch()
|
||||||
|
|
||||||
|
# Clear the bottom of the screen
|
||||||
|
clear(instance, instance.height - 1, 0)
|
||||||
|
110
main.py
Normal file
110
main.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
from core import colors, cursors, buffers, modes, utils
|
||||||
|
from core.buffers import Buffer
|
||||||
|
from core.components import Components
|
||||||
|
import traceback
|
||||||
|
import argparse
|
||||||
|
import curses
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class Lambda:
|
||||||
|
def __init__(self, buffer: Buffer):
|
||||||
|
self.screen = curses.initscr()
|
||||||
|
self.buffer = buffer
|
||||||
|
self.cursor = [0, 0]
|
||||||
|
self.mode = "normal"
|
||||||
|
self.components = Components()
|
||||||
|
self.height = self.screen.getmaxyx()[0]
|
||||||
|
self.width = self.screen.getmaxyx()[1]
|
||||||
|
self.safe_height = self.height - len(self.components.components["bottom"])
|
||||||
|
self.config = {"icon": "λ"}
|
||||||
|
|
||||||
|
def update_dimensions(self):
|
||||||
|
self.height, self.width = self.screen.getmaxyx()
|
||||||
|
self.safe_height = self.height - len(self.components.components["bottom"])
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
# Update the dimensions
|
||||||
|
self.update_dimensions()
|
||||||
|
|
||||||
|
# Refresh the on-screen components
|
||||||
|
self.components.render(self)
|
||||||
|
|
||||||
|
# Move the cursor
|
||||||
|
cursors.cursor_move(self.screen, self.cursor)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
# Initialise colors
|
||||||
|
colors.init_colors()
|
||||||
|
|
||||||
|
# Change the cursor shape
|
||||||
|
cursors.cursor_mode("block")
|
||||||
|
|
||||||
|
# Turn no echo on
|
||||||
|
curses.noecho()
|
||||||
|
|
||||||
|
# Show a welcome message if lambda opens with no file
|
||||||
|
if not self.buffer.path:
|
||||||
|
utils.welcome(self.screen)
|
||||||
|
|
||||||
|
# Main loop
|
||||||
|
self.run()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
# Write the buffer to the screen
|
||||||
|
# buffers.write_buffer(screen, buffer)
|
||||||
|
|
||||||
|
# Update the screen
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
# Wait for a keypress
|
||||||
|
key = self.screen.getch()
|
||||||
|
|
||||||
|
# Handle the key
|
||||||
|
modes.handle_key(self, key)
|
||||||
|
|
||||||
|
# Refresh and clear the screen
|
||||||
|
self.screen.refresh()
|
||||||
|
self.screen.clear()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Command line arguments
|
||||||
|
parser = argparse.ArgumentParser(description="Next generation hackable text editor for nerds.")
|
||||||
|
parser.add_argument("file", metavar="file", type=str, nargs="?",
|
||||||
|
help="The name of a file for lambda to open")
|
||||||
|
|
||||||
|
# Collect the arguments passed into lambda
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Load the file into buffer
|
||||||
|
buffer = buffers.load_file(args.file)
|
||||||
|
|
||||||
|
# Change the escape delay to 25ms
|
||||||
|
# Fixes an issue where esc takes way too long to press
|
||||||
|
os.environ.setdefault("ESCDELAY", "25")
|
||||||
|
|
||||||
|
# Load lambda with the buffer
|
||||||
|
screen = Lambda(buffer)
|
||||||
|
|
||||||
|
# Start the screen
|
||||||
|
try:
|
||||||
|
screen.start()
|
||||||
|
|
||||||
|
# KeyboardInterrupt is thrown when ctrl+c is pressed
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
curses.endwin()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
except Exception as exception:
|
||||||
|
curses.endwin()
|
||||||
|
print(f"{colors.Codes.red}FATAL ERROR:{colors.Codes.end} "
|
||||||
|
f"{colors.Codes.yellow}{exception}{colors.Codes.end}\n")
|
||||||
|
print(traceback.format_exc())
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
34
mode/command.py
Normal file
34
mode/command.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from core import utils
|
||||||
|
|
||||||
|
|
||||||
|
def execute(instance, commands):
|
||||||
|
if not commands:
|
||||||
|
# Quit if there are no commands, don't check anything
|
||||||
|
return instance
|
||||||
|
|
||||||
|
for command in commands:
|
||||||
|
if command == "w":
|
||||||
|
# Write to the file
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif command == "q":
|
||||||
|
# Load a goodbye prompt
|
||||||
|
utils.goodbye(instance)
|
||||||
|
|
||||||
|
else:
|
||||||
|
utils.error(instance, f"not an editor command: '{command}'")
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
def activate(instance):
|
||||||
|
# Start the prompt
|
||||||
|
commands = utils.prompt(instance, ":")
|
||||||
|
|
||||||
|
# Execute the commands
|
||||||
|
instance = execute(instance, commands)
|
||||||
|
|
||||||
|
# Return to normal mode
|
||||||
|
instance.mode = "normal"
|
||||||
|
|
||||||
|
return instance
|
18
mode/insert.py
Normal file
18
mode/insert.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from core import cursors
|
||||||
|
from mode import normal
|
||||||
|
|
||||||
|
|
||||||
|
def execute(instance, key):
|
||||||
|
if key == 27:
|
||||||
|
# Switch to normal mode
|
||||||
|
instance.mode = "normal"
|
||||||
|
normal.activate(instance)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
def activate(instance):
|
||||||
|
# Switch the cursor to a line
|
||||||
|
cursors.cursor_mode("line")
|
||||||
|
|
||||||
|
return instance
|
45
mode/normal.py
Normal file
45
mode/normal.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
from core import cursors, modes
|
||||||
|
from mode import insert
|
||||||
|
from mode import command
|
||||||
|
|
||||||
|
|
||||||
|
def execute(instance, key):
|
||||||
|
if key == ord("j"):
|
||||||
|
# Move the cursor down
|
||||||
|
instance.cursor = cursors.cursor_push(instance.cursor, "down")
|
||||||
|
|
||||||
|
elif key == ord("k"):
|
||||||
|
# Move the cursor up
|
||||||
|
instance.cursor = cursors.cursor_push(instance.cursor, "up")
|
||||||
|
|
||||||
|
elif key == ord("l"):
|
||||||
|
# Move the cursor right
|
||||||
|
instance.cursor = cursors.cursor_push(instance.cursor, "right")
|
||||||
|
|
||||||
|
elif key == ord("h"):
|
||||||
|
# Move the cursor left
|
||||||
|
instance.cursor = cursors.cursor_push(instance.cursor, "left")
|
||||||
|
|
||||||
|
elif key == ord("i"):
|
||||||
|
# Activate insert mode
|
||||||
|
instance = modes.activate(instance, "insert")
|
||||||
|
|
||||||
|
elif key == ord("I"):
|
||||||
|
# Move the cursor to the right
|
||||||
|
instance.cursor = cursors.cursor_push(instance.cursor, "right")
|
||||||
|
|
||||||
|
# Then activate insert mode
|
||||||
|
instance = modes.activate(instance, "insert")
|
||||||
|
|
||||||
|
elif key in (ord(":"), ord(";")):
|
||||||
|
# Activate command mode
|
||||||
|
instance = modes.activate(instance, "command")
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
def activate(instance):
|
||||||
|
# Switch the cursor to a block
|
||||||
|
cursors.cursor_mode("block")
|
||||||
|
|
||||||
|
return instance
|
Loading…
Reference in New Issue
Block a user