Start moving code to separate functions to prototype func eval
This commit is contained in:
parent
43450a8c37
commit
cd8c8739b0
17
editing.py
Normal file
17
editing.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from fide import *
|
||||||
|
|
||||||
|
global ctx
|
||||||
|
ctx = GlobalContext()
|
||||||
|
|
||||||
|
# def cursor_go_left():
|
||||||
|
def go_left():
|
||||||
|
buf = ctx.current_buffer
|
||||||
|
cursor = ctx.current_buffer.cursor
|
||||||
|
if cursor.col == 0:
|
||||||
|
if cursor.line_num > 0:
|
||||||
|
cursor.col = buf.lines[cursor.line_num-1].length
|
||||||
|
cursor.want_col = cursor.col
|
||||||
|
cursor.line_num -= 1
|
||||||
|
else:
|
||||||
|
cursor.col = max(0, cursor.col - 1)
|
||||||
|
cursor.want_col = cursor.col
|
275
fide.py
275
fide.py
@ -9,24 +9,96 @@ import sys
|
|||||||
import time
|
import time
|
||||||
import copy
|
import copy
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from code import InteractiveConsole, InteractiveInterpreter
|
||||||
|
from editing import *
|
||||||
|
|
||||||
|
@dataclass(slots=True)
|
||||||
class Cursor:
|
class Cursor:
|
||||||
def __init__(self, row, col):
|
width: float
|
||||||
self.row: int = 0
|
height: float
|
||||||
self.col: int = 0
|
line_num: int = 0
|
||||||
self.want_col: int = 0
|
col: int = 0
|
||||||
|
want_col: int = 0
|
||||||
|
|
||||||
def pos(self):
|
@dataclass(slots=True)
|
||||||
return (self.row, self.col)
|
class Line:
|
||||||
|
piece: PieceTable
|
||||||
class Row:
|
length: int
|
||||||
def __init__(self, text):
|
|
||||||
self.text = PieceTable(text)
|
|
||||||
self.length = len(text)
|
|
||||||
|
|
||||||
|
@dataclass(slots=True)
|
||||||
class Buffer:
|
class Buffer:
|
||||||
def __init__(self, raw_text):
|
lines: List[Line]
|
||||||
pass
|
cursor: Cursor
|
||||||
|
|
||||||
|
|
||||||
|
def cursor_pos(cursor: Cursor):
|
||||||
|
return (cursor.line_num, cursor.col)
|
||||||
|
|
||||||
|
def cursor_draw(cursor: Cursor):
|
||||||
|
rect = Rect(cursor.col * cursor.width, cursor.line_num * cursor.height, 3, cursor.height)
|
||||||
|
pg.draw.rect(screen, "black", rect, width=2)
|
||||||
|
|
||||||
|
def line_create(text: str) -> Line:
|
||||||
|
return Line(PieceTable(text), len(text))
|
||||||
|
|
||||||
|
def buffer_create(text: str, cursor: Cursor) -> Buffer:
|
||||||
|
lines = []
|
||||||
|
for line in text.split('\n'):
|
||||||
|
lines.append(line_create(line))
|
||||||
|
return Buffer(lines, cursor)
|
||||||
|
|
||||||
|
def buffer_line_current(buf: Buffer) -> Line:
|
||||||
|
return buf.lines[buf.cursor.line_num]
|
||||||
|
|
||||||
|
def buffer_line_num(buf: Buffer) -> int:
|
||||||
|
return buf.cursor.line_num
|
||||||
|
|
||||||
|
def buffer_total_lines(buf: Buffer) -> int:
|
||||||
|
return len(buf.lines)
|
||||||
|
|
||||||
|
def buffer_line_len(buf: Buffer) -> int:
|
||||||
|
return buffer_line_current(buf).length
|
||||||
|
|
||||||
|
def buffer_insert_line_below(buf: Buffer, text):
|
||||||
|
line_num = buffer_line_num(buf)
|
||||||
|
buf.lines.insert(line_num + 1, line_create(text))
|
||||||
|
|
||||||
|
def buffer_newline_at_pos(buf):
|
||||||
|
curr_line = buffer_line_current(buf)
|
||||||
|
cursor = buf.cursor
|
||||||
|
if cursor.col < buffer_line_len(buf):
|
||||||
|
remainder = curr_line.length - cursor.col
|
||||||
|
line = curr_line.piece.string_at(cursor.col, remainder)
|
||||||
|
curr_line.piece.delete(cursor.col, remainder)
|
||||||
|
curr_line.length -= remainder
|
||||||
|
else:
|
||||||
|
line = ""
|
||||||
|
buffer_insert_line_below(buf, line)
|
||||||
|
cursor.line_num += 1
|
||||||
|
# Eventually when we need to be indentation aware
|
||||||
|
cursor.col = 0
|
||||||
|
cursor.want_col = 0
|
||||||
|
|
||||||
|
|
||||||
|
def buffer_delete_character_at_pos(buf):
|
||||||
|
cursor = buf.cursor
|
||||||
|
if cursor_pos(cursor) != (0,0):
|
||||||
|
if cursor.col == 0:
|
||||||
|
curr_line = buf.lines.pop(cursor.line_num)
|
||||||
|
cursor.line_num -= 1
|
||||||
|
above_row = buf.lines[cursor.line_num]
|
||||||
|
above_row.piece.insert(curr_line.piece.get_text(), above_row.length)
|
||||||
|
cursor.col = above_row.length
|
||||||
|
cursor.want_col = cursor.col
|
||||||
|
above_row.length += curr_line.length
|
||||||
|
else:
|
||||||
|
curr_line = buffer_line_current(buf)
|
||||||
|
curr_line.piece.delete(cursor.col - 1, 1)
|
||||||
|
curr_line.length -= 1
|
||||||
|
cursor.col = max(0, cursor.col - 1)
|
||||||
|
cursor.want_col = cursor.col
|
||||||
|
|
||||||
oswinx, oswiny = 1940,50
|
oswinx, oswiny = 1940,50
|
||||||
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (oswinx,oswiny)
|
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (oswinx,oswiny)
|
||||||
@ -38,28 +110,30 @@ text_renderer = pg.font.SysFont('JetBrains Mono', 14)
|
|||||||
screen = pg.display.set_mode((900, 900), pg.RESIZABLE)
|
screen = pg.display.set_mode((900, 900), pg.RESIZABLE)
|
||||||
pg.key.set_repeat(240, 10)
|
pg.key.set_repeat(240, 10)
|
||||||
|
|
||||||
rows = []
|
def load_file(path):
|
||||||
cursor = Cursor(0, 0)
|
with open(path, 'r', encoding='utf-8') as f:
|
||||||
line_height = 20
|
text = f.read()
|
||||||
char_width = 8
|
f.close()
|
||||||
|
return text
|
||||||
|
|
||||||
with open('../gux/test.c', 'r', encoding='utf-8') as f:
|
@dataclass
|
||||||
text = f.read()
|
class GlobalContext:
|
||||||
for line in text.split('\n'):
|
cursor = Cursor(width=8, height=20)
|
||||||
rows.append(Row(line))
|
text = load_file('../gux/test.c')
|
||||||
# print(current_buffer[120:125])
|
current_buffer = buffer_create(text, cursor)
|
||||||
f.close()
|
|
||||||
|
|
||||||
def draw_cursor():
|
# global ctx
|
||||||
rect = Rect(cursor.col * char_width, cursor.row * line_height, 3, line_height)
|
def main():
|
||||||
pg.draw.rect(screen, "black", rect, width=2)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
running = True
|
running = True
|
||||||
# print(current_buffer.display())
|
|
||||||
frame_count = 0
|
frame_count = 0
|
||||||
cursor_flash = 0
|
cursor_flash = 0
|
||||||
cursor_on = True
|
cursor_on = True
|
||||||
|
line_height = 20
|
||||||
|
|
||||||
|
cursor = ctx.cursor
|
||||||
|
current_buffer = ctx.current_buffer
|
||||||
|
console = InteractiveInterpreter(locals())
|
||||||
|
console.runsource('from editing import *')
|
||||||
while running:
|
while running:
|
||||||
dt = clock.tick(120) / 1000.0
|
dt = clock.tick(120) / 1000.0
|
||||||
screen.fill('white')
|
screen.fill('white')
|
||||||
@ -68,101 +142,73 @@ if __name__ == '__main__':
|
|||||||
if event.type == pg.QUIT:
|
if event.type == pg.QUIT:
|
||||||
running = False
|
running = False
|
||||||
if event.type == pg.KEYDOWN:
|
if event.type == pg.KEYDOWN:
|
||||||
# print(frame_count, event.unicode, pg.key.name(event.key), event.mod, end="")
|
|
||||||
# print("")
|
|
||||||
# print(event.mod)
|
|
||||||
cursor_on = True
|
cursor_on = True
|
||||||
cursor_flash = 0
|
cursor_flash = 0
|
||||||
row = rows[cursor.row]
|
curr_line = buffer_line_current(current_buffer)
|
||||||
if event.key == pg.K_RETURN:
|
if event.mod == 64: # Right Ctrl
|
||||||
if cursor.col < row.length:
|
|
||||||
remainder = row.length - cursor.col
|
|
||||||
line = row.text.string_at(cursor.col, remainder)
|
|
||||||
row.text.delete(cursor.col, remainder)
|
|
||||||
row.length -= remainder
|
|
||||||
else:
|
|
||||||
line = ""
|
|
||||||
rows.insert(cursor.row+1, Row(str(line)))
|
|
||||||
cursor.row += 1
|
|
||||||
# Eventually when we need to be indentation aware
|
|
||||||
cursor.col = 0
|
|
||||||
cursor.want_col = 0
|
|
||||||
elif event.key == pg.K_BACKSPACE:
|
|
||||||
if cursor.pos() != (0,0):
|
|
||||||
if cursor.col == 0:
|
|
||||||
row = rows.pop(cursor.row)
|
|
||||||
cursor.row -= 1
|
|
||||||
above_row = rows[cursor.row]
|
|
||||||
above_row.text.insert(row.text.get_text(), above_row.length)
|
|
||||||
cursor.col = above_row.length
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
above_row.length += row.length
|
|
||||||
else:
|
|
||||||
row.text.delete(cursor.col - 1, 1)
|
|
||||||
row.length -= 1
|
|
||||||
cursor.col = max(0, cursor.col - 1)
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
elif event.key == pg.K_DELETE:
|
|
||||||
if cursor.col >= rows[cursor.row].length:
|
|
||||||
if cursor.row < len(rows) - 1:
|
|
||||||
below_row = rows.pop(cursor.row+1)
|
|
||||||
if below_row.length > 0:
|
|
||||||
row.text.insert(below_row.text.get_text(), row.length)
|
|
||||||
row.length += below_row.length
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
else:
|
|
||||||
if row.length >= 1:
|
|
||||||
row.text.delete(cursor.col, 1)
|
|
||||||
row.length -= 1
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
elif event.key == pg.K_LEFT:
|
|
||||||
if cursor.col == 0:
|
|
||||||
if cursor.row > 0:
|
|
||||||
cursor.col = rows[cursor.row-1].length
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
cursor.row -= 1
|
|
||||||
else:
|
|
||||||
cursor.col = max(0, cursor.col - 1)
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
elif event.key == pg.K_RIGHT:
|
|
||||||
if cursor.col == rows[cursor.row].length:
|
|
||||||
if cursor.row < len(rows):
|
|
||||||
cursor.col = 0
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
cursor.row += 1
|
|
||||||
else:
|
|
||||||
cursor.col = min(rows[cursor.row].length, cursor.col + 1)
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
elif event.key == pg.K_UP:
|
|
||||||
cursor.row = max(0, cursor.row - 1)
|
|
||||||
cursor.col = min(cursor.want_col, rows[cursor.row].length)
|
|
||||||
elif event.key == pg.K_DOWN:
|
|
||||||
cursor.row = min(len(rows) - 1, cursor.row + 1)
|
|
||||||
cursor.col = min(cursor.want_col, rows[cursor.row].length)
|
|
||||||
elif event.key == pg.K_SPACE:
|
|
||||||
row.text.insert(u' ', cursor.col)
|
|
||||||
row.length += 1
|
|
||||||
cursor.col += 1
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
elif event.key >= 33 and event.key <= 126 and event.mod < 2:
|
|
||||||
row.text.insert(event.unicode, cursor.col)
|
|
||||||
row.length += 1
|
|
||||||
cursor.col += 1
|
|
||||||
cursor.want_col = cursor.col
|
|
||||||
elif event.mod == 64: # Right Ctrl
|
|
||||||
if event.key == pg.K_e:
|
if event.key == pg.K_e:
|
||||||
cursor.col = rows[cursor.row].length
|
cursor.col = buffer_line_len(buf)
|
||||||
cursor.want_col = cursor.col
|
cursor.want_col = cursor.col
|
||||||
if event.key == pg.K_a:
|
if event.key == pg.K_a:
|
||||||
cursor.col = 0
|
cursor.col = 0
|
||||||
cursor.want_col = cursor.col
|
cursor.want_col = cursor.col
|
||||||
|
if event.key == pg.K_RETURN:
|
||||||
|
src = buffer_line_current(current_buffer).piece.get_text()
|
||||||
|
console.runsource(src[3:])
|
||||||
|
# console.runcode()
|
||||||
|
elif event.key == pg.K_RETURN:
|
||||||
|
buffer_newline_at_pos(current_buffer)
|
||||||
|
elif event.key == pg.K_BACKSPACE:
|
||||||
|
buffer_delete_character_at_pos(current_buffer)
|
||||||
|
elif event.key == pg.K_DELETE:
|
||||||
|
if cursor.col >= buffer_line_len(current_buffer):
|
||||||
|
if cursor.line_num < len(current_buffer.lines) - 1:
|
||||||
|
below_row = current_buffer.lines.pop(cursor.line_num+1)
|
||||||
|
if below_row.length > 0:
|
||||||
|
curr_line.piece.insert(below_row.piece.get_text(), curr_line.length)
|
||||||
|
curr_line.length += below_row.length
|
||||||
|
cursor.want_col = cursor.col
|
||||||
|
else:
|
||||||
|
if curr_line.length >= 1:
|
||||||
|
curr_line.piece.delete(cursor.col, 1)
|
||||||
|
curr_line.length -= 1
|
||||||
|
cursor.want_col = cursor.col
|
||||||
|
elif event.key == pg.K_LEFT:
|
||||||
|
cursor_go_left(current_buffer)
|
||||||
|
elif event.key == pg.K_RIGHT:
|
||||||
|
if cursor.col == buffer_line_len(current_buffer):
|
||||||
|
if cursor.line_num < buffer_total_lines(current_buffer) - 1:
|
||||||
|
cursor.col = 0
|
||||||
|
cursor.want_col = cursor.col
|
||||||
|
cursor.line_num += 1
|
||||||
|
else:
|
||||||
|
cursor.col = min(buffer_line_len(current_buffer), cursor.col + 1)
|
||||||
|
cursor.want_col = cursor.col
|
||||||
|
elif event.key == pg.K_UP:
|
||||||
|
cursor.line_num = max(0, cursor.line_num - 1)
|
||||||
|
line_len = buffer_line_len(current_buffer)
|
||||||
|
cursor.col = min(cursor.want_col, line_len)
|
||||||
|
elif event.key == pg.K_DOWN:
|
||||||
|
line_len = buffer_line_len(current_buffer)
|
||||||
|
cursor.line_num = min(len(current_buffer.lines) - 1, cursor.line_num + 1)
|
||||||
|
cursor.col = min(cursor.want_col, line_len)
|
||||||
|
elif event.key == pg.K_SPACE:
|
||||||
|
curr_line.piece.insert(u' ', cursor.col)
|
||||||
|
curr_line.length += 1
|
||||||
|
cursor.col += 1
|
||||||
|
cursor.want_col = cursor.col
|
||||||
|
elif event.key >= 33 and event.key <= 126 and event.mod < 2:
|
||||||
|
curr_line.piece.insert(event.unicode, cursor.col)
|
||||||
|
curr_line.length += 1
|
||||||
|
cursor.col += 1
|
||||||
|
cursor.want_col = cursor.col
|
||||||
|
|
||||||
for i,row in enumerate(rows):
|
for i,curr_line in enumerate(current_buffer.lines):
|
||||||
render = text_renderer.render(row.text.get_text(), True, 'black')
|
render = text_renderer.render(curr_line.piece.get_text(), True, 'black')
|
||||||
screen.blit(render, (0, i * line_height))
|
screen.blit(render, (0, i * line_height))
|
||||||
|
|
||||||
if cursor_on and cursor_flash < 0.5:
|
if cursor_on and cursor_flash < 0.5:
|
||||||
draw_cursor()
|
cursor_draw(cursor)
|
||||||
elif cursor_on:
|
elif cursor_on:
|
||||||
cursor_on = False
|
cursor_on = False
|
||||||
cursor_flash = 0
|
cursor_flash = 0
|
||||||
@ -172,3 +218,6 @@ if __name__ == '__main__':
|
|||||||
cursor_flash += dt
|
cursor_flash += dt
|
||||||
|
|
||||||
pg.display.flip()
|
pg.display.flip()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user