181 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
		
			5.1 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
 | 
						|
 | 
						|
@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 
 | 
						|
 | 
						|
def translate_keyname(keyname: str) -> str:
 | 
						|
    match keyname:
 | 
						|
        case 'left ctrl':
 | 
						|
            return 'C-'
 | 
						|
        case 'left alt':
 | 
						|
            return 'A-'
 | 
						|
        case 'left meta':
 | 
						|
            return 'M-'
 | 
						|
        case 'left shift':
 | 
						|
            return 'S-'
 | 
						|
 | 
						|
        case 'right ctrl':
 | 
						|
            return 'RC-'
 | 
						|
        case 'right alt':
 | 
						|
            return 'RA-'
 | 
						|
        case 'right meta':
 | 
						|
            return 'RM-'
 | 
						|
        case 'right shift':
 | 
						|
            return 'RS-'
 | 
						|
 | 
						|
 | 
						|
# oswinx, oswiny = 1940,50
 | 
						|
oswinx, oswiny = 20,50
 | 
						|
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (oswinx,oswiny)
 | 
						|
os.environ['SDL_VIDEO_X11_WMCLASS'] = "pygame"
 | 
						|
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
 | 
						|
global ctx
 | 
						|
ctx = GlobalContext()
 | 
						|
from config import *
 | 
						|
from editing import *
 | 
						|
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 *')
 | 
						|
    while running:
 | 
						|
        dt = clock.tick(120) / 1000.0
 | 
						|
        screen.fill('white')
 | 
						|
        frame_count += 1
 | 
						|
        for event in pg.event.get():
 | 
						|
            # print(pg.event.event_name(event.type))
 | 
						|
            if event.type == pg.QUIT:
 | 
						|
                running = False
 | 
						|
            if event.type == pg.KEYDOWN:
 | 
						|
                # print(pg.key.name(event.key))
 | 
						|
                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_go_end_line()
 | 
						|
                    if event.key == pg.K_a:
 | 
						|
                        cursor_go_beginning_line()
 | 
						|
                    if event.key == pg.K_RETURN:
 | 
						|
                        src = buffer_line_current(current_buffer).piece.get_text()
 | 
						|
                        # try:
 | 
						|
                        #     eval(src[3:])
 | 
						|
                        # except:
 | 
						|
                        #     print('error evaluating line: ' + src[3:])
 | 
						|
                        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 pg.key.name(event.key) in keymap:
 | 
						|
                    keymap[pg.key.name(event.key)]()
 | 
						|
                    # pass
 | 
						|
                # elif event.mod < 2:
 | 
						|
                elif event.unicode:
 | 
						|
                    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()
 |