Last active
March 15, 2023 06:31
-
-
Save Pinacolada64/62415d4a4216976685f4ae3f0955fbf9 to your computer and use it in GitHub Desktop.
Beginning a simple line-based text editor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
try: | |
import getch | |
except ImportError as e: | |
print(f"Can't import getch: {e}.") | |
def get_character(): | |
""" | |
Wait for a character to be typed | |
return tuple: 'in_char': character, 'asc': ascii value | |
""" | |
in_char = None | |
while in_char is None: | |
# getch.getch() does not echo input | |
in_char = getch.getch() | |
asc = ord(in_char) | |
return (in_char, asc) | |
def out_backspace(count): | |
""" | |
Output <count> backspaces, character used depends on terminal | |
""" | |
backspace = "\b \b" # Linux terminal | |
# if Character.terminal['translation'] == "PetSCII" then: | |
# backspace = chr(20) | |
output = backspace * count | |
return output | |
def yes_or_no(prompt="Are you sure", default=False): | |
""" | |
Ask a yes-or-no question, with default answer. | |
the response is yes (True), or no (False). | |
prompt: configurable string | |
default: unless any other key but 'y' for True or 'n' for False is typed | |
returns: response: yes = True, no = False | |
""" | |
if default is True: | |
chars = "Y/n" | |
if default is False: | |
chars = "y/N" | |
print(f"{prompt} [{chars}]: ", end="", flush=True) | |
key, asc = get_character() | |
command_char = key.lower() | |
if default is True and command_char != "n": | |
response = True | |
print("Yes.\n") | |
if default is False and command_char != "y": | |
response = False | |
print("No.\n") | |
return response | |
def dot_cmd_list(): | |
""" | |
list text with line numbers | |
""" | |
for k, v in enumerate(buffer, start=1): | |
print(f"{k}:\n{v}") | |
print("Using getch:") | |
# init: | |
editing = True | |
buffer = ['', ''] # empty buffer, but 1-indexed | |
char_pos = 0 | |
line = '' # init empty line | |
line_num = 0 | |
char_pos = 0 | |
KEY_BACKSPACE = 127 | |
KEY_RETURN = 10 # last char of CR/LF pair | |
prompt = "Command: " | |
debug = True | |
""" | |
editing: Boolean whether we're in the editor | |
char_pos: character position within line | |
line: the string input so far | |
line_num: the line number being edited (1-based) | |
char: character typed | |
asc: ascii value of char | |
""" | |
while editing is True: | |
char, asc = get_character() | |
# asc = ord(char) # ascii value | |
# handle column 0 dot/slash commands: | |
if char_pos == 0: | |
# print(char, asc) | |
if char in ("/", "."): | |
print(prompt, end="", flush=True) | |
key, asc = get_character() | |
command_char = key.lower() | |
if command_char == "a": | |
print("Abort") | |
response = yes_or_no(default=False) | |
if response is True: | |
editing = False | |
continue | |
if command_char == "l": | |
print("List") | |
dot_cmd_list() | |
continue | |
if command_char == "n": | |
print("Erase Text") | |
response = yes_or_no(default=False) | |
if response is True: | |
buffer = ['', ''] | |
print("Erased text.") | |
continue | |
if asc == KEY_BACKSPACE or asc == KEY_RETURN or command_char in ("/", "."): | |
print(out_backspace(len(prompt)), end='', flush=True) | |
continue | |
else: | |
print(f"{command_char} ({asc}) not implemented yet.") | |
# handle backspace/delete: | |
if asc == KEY_BACKSPACE and char_pos > 0: | |
# print("BS/DEL", end='') | |
char_pos -= 1 | |
line = line[:char_pos] | |
print(out_backspace(1), end='', flush=True) | |
elif asc == 10: | |
# print(" [Return/Enter hit]\n") | |
print() | |
# if line_num > len(buffer): | |
# buffer.append(x for x in [line_num - len(buffer)] | |
# TODO: fill in blank lines | |
buffer[line_num] = line | |
line_num += 1 | |
line = '' | |
char_pos = 0 | |
else: | |
# filter out control chars for now: | |
if asc > 31 and asc < 197: | |
# print(f"{asc if debug else ''}{char}", end='', flush=True) | |
print(f"{char}", end='', flush=True) | |
char_pos += 1 | |
line = line + char |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment