169 lines
4.9 KiB
Python
Executable File
169 lines
4.9 KiB
Python
Executable File
import pygame as pg
|
|
from pygame import Rect
|
|
|
|
from piece_table import PieceTable
|
|
|
|
import os
|
|
import json
|
|
import sys
|
|
import time
|
|
import copy
|
|
from dataclasses import dataclass
|
|
from typing import List
|
|
|
|
from code import InteractiveConsole, InteractiveInterpreter
|
|
from editing import *
|
|
|
|
@dataclass(slots=True)
|
|
class Cursor:
|
|
width: float
|
|
height: float
|
|
line_num: int = 0
|
|
col: int = 0
|
|
want_col: int = 0
|
|
|
|
@dataclass(slots=True)
|
|
class Line:
|
|
piece: PieceTable
|
|
length: int
|
|
|
|
@dataclass(slots=True)
|
|
class Buffer:
|
|
lines: List[Line]
|
|
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
|
|
|
|
|
|
oswinx, oswiny = 1940,50
|
|
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (oswinx,oswiny)
|
|
clock = pg.time.Clock()
|
|
|
|
pg.init()
|
|
pg.font.init()
|
|
text_renderer = pg.font.SysFont('JetBrains Mono', 14)
|
|
screen = pg.display.set_mode((900, 900), pg.RESIZABLE)
|
|
pg.key.set_repeat(240, 10)
|
|
|
|
def load_file(path):
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
text = f.read()
|
|
f.close()
|
|
return text
|
|
|
|
@dataclass
|
|
class GlobalContext:
|
|
cursor = Cursor(width=8, height=20)
|
|
text = load_file('../gux/test.c')
|
|
current_buffer = buffer_create(text, cursor)
|
|
|
|
# global ctx
|
|
def main():
|
|
running = True
|
|
frame_count = 0
|
|
cursor_flash = 0
|
|
cursor_on = True
|
|
line_height = 20
|
|
|
|
cursor = ctx.cursor
|
|
current_buffer = ctx.current_buffer
|
|
console = InteractiveInterpreter(locals())
|
|
console.runsource('from editing import *')
|
|
key_map = {
|
|
'left': cursor_go_left,
|
|
'right': cursor_go_right,
|
|
'up': cursor_go_up,
|
|
'down': cursor_go_down
|
|
}
|
|
while running:
|
|
dt = clock.tick(120) / 1000.0
|
|
screen.fill('white')
|
|
frame_count += 1
|
|
for event in pg.event.get():
|
|
if event.type == pg.QUIT:
|
|
running = False
|
|
if event.type == pg.KEYDOWN:
|
|
cursor_on = True
|
|
cursor_flash = 0
|
|
curr_line = buffer_line_current(current_buffer)
|
|
if event.mod == 64: # Right Ctrl
|
|
if event.key == pg.K_e:
|
|
cursor.col = buffer_line_len(buf)
|
|
cursor.want_col = cursor.col
|
|
if event.key == pg.K_a:
|
|
cursor.col = 0
|
|
cursor.want_col = cursor.col
|
|
if event.key == pg.K_RETURN:
|
|
src = buffer_line_current(current_buffer).piece.get_text()
|
|
console.runsource(src[3:])
|
|
elif event.key == pg.K_RETURN:
|
|
buffer_newline_at_pos()
|
|
elif event.key == pg.K_BACKSPACE:
|
|
buffer_delete_character_under_cursor()
|
|
elif event.key == pg.K_DELETE:
|
|
buffer_delete_next_character()
|
|
elif event.key == pg.K_LEFT:
|
|
key_map['left']()
|
|
elif event.key == pg.K_RIGHT:
|
|
key_map['right']()
|
|
elif event.key == pg.K_UP:
|
|
key_map['up']()
|
|
elif event.key == pg.K_DOWN:
|
|
key_map['down']()
|
|
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,curr_line in enumerate(current_buffer.lines):
|
|
render = text_renderer.render(curr_line.piece.get_text(), True, 'black')
|
|
screen.blit(render, (0, i * line_height))
|
|
|
|
if cursor_on and cursor_flash < 0.5:
|
|
cursor_draw(cursor)
|
|
elif cursor_on:
|
|
cursor_on = False
|
|
cursor_flash = 0
|
|
elif not cursor_on and cursor_flash > 0.5:
|
|
cursor_on = True
|
|
cursor_flash = 0
|
|
cursor_flash += dt
|
|
|
|
pg.display.flip()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|