Add buffer saving with keybinding
This commit is contained in:
parent
e8ea80ff66
commit
dfdadef143
BIN
JetBrainsMono-Regular.otf
Normal file
BIN
JetBrainsMono-Regular.otf
Normal file
Binary file not shown.
@ -11,6 +11,7 @@ kb('insert', 'escape', lambda: keymap_push(keymappings['normal']))
|
||||
kb('insert', 'backspace', buffer_delete_character_under_cursor)
|
||||
kb('insert', 'delete', buffer_delete_next_character)
|
||||
kb('insert', 'return', buffer_newline_at_pos)
|
||||
kb('insert', 'C-s', buffer_save)
|
||||
kb('normal', 'i', keymap_pop)
|
||||
kb('normal', 'H', cursor_go_buffer_beginning)
|
||||
kb('normal', 'L', cursor_go_buffer_end)
|
||||
@ -20,3 +21,4 @@ kb('normal', 'k', cursor_go_up)
|
||||
kb('normal', 'l', cursor_go_right)
|
||||
kb('normal', '^', cursor_go_line_beginning)
|
||||
kb('normal', '$', cursor_go_line_end)
|
||||
kb('normal', 'C-s', buffer_save)
|
||||
|
@ -141,3 +141,10 @@ def buffer_insert_text_at_cursor(text):
|
||||
|
||||
# def buffer_switch_insert_mode():
|
||||
# ctx.current_buffer.mode = 'insert'
|
||||
|
||||
def buffer_save():
|
||||
buf = ctx.current_buffer
|
||||
# if buf.filepath is not None:
|
||||
with open(buf.filepath, 'w') as f:
|
||||
text = '\n'.join(map(lambda l: l.piece.get_text(), buf.lines))
|
||||
f.write(text)
|
||||
|
31
fide.py
31
fide.py
@ -9,7 +9,7 @@ import sys
|
||||
import time
|
||||
import copy
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
from code import InteractiveConsole, InteractiveInterpreter
|
||||
|
||||
@ -23,6 +23,8 @@ class Cursor:
|
||||
|
||||
@dataclass(slots=True)
|
||||
class Line:
|
||||
# Making this a PieceTable rather than a string is rather pointless right now
|
||||
# But it's easier to operate on rows for the time being
|
||||
piece: PieceTable
|
||||
length: int
|
||||
|
||||
@ -30,7 +32,7 @@ class Line:
|
||||
class Buffer:
|
||||
lines: List[Line]
|
||||
cursor: Cursor
|
||||
mode: str = 'insert'
|
||||
filepath: Optional[str] = None
|
||||
|
||||
def cursor_pos(cursor: Cursor):
|
||||
return (cursor.line_num, cursor.col)
|
||||
@ -42,11 +44,11 @@ def cursor_draw(cursor: Cursor):
|
||||
def line_create(text: str) -> Line:
|
||||
return Line(PieceTable(text), len(text))
|
||||
|
||||
def buffer_create(text: str, cursor: Cursor) -> Buffer:
|
||||
def buffer_create(text: str, filepath: str, cursor: Cursor) -> Buffer:
|
||||
lines = []
|
||||
for line in text.split('\n'):
|
||||
lines.append(line_create(line))
|
||||
return Buffer(lines, cursor)
|
||||
return Buffer(lines, cursor, filepath)
|
||||
|
||||
def buffer_line_current(buf: Buffer) -> Line:
|
||||
return buf.lines[buf.cursor.line_num]
|
||||
@ -69,7 +71,7 @@ clock = pg.time.Clock()
|
||||
|
||||
pg.init()
|
||||
pg.font.init()
|
||||
text_renderer = pg.font.SysFont('JetBrains Mono', 14)
|
||||
text_renderer = pg.font.Font('JetBrainsMono-Regular.otf', 14)
|
||||
screen = pg.display.set_mode((900, 900), pg.RESIZABLE)
|
||||
pg.key.set_repeat(240, 10)
|
||||
|
||||
@ -81,13 +83,18 @@ def load_file(path):
|
||||
|
||||
@dataclass
|
||||
class GlobalContext:
|
||||
cursor = Cursor(width=8, height=20)
|
||||
text = load_file('../gux/test.c')
|
||||
current_buffer = buffer_create(text, cursor)
|
||||
text: str
|
||||
current_buffer: Buffer
|
||||
cursor: Cursor
|
||||
|
||||
# global ctx
|
||||
global ctx
|
||||
ctx = GlobalContext()
|
||||
cursor = Cursor(width=8, height=20)
|
||||
if len(sys.argv) <= 1:
|
||||
ctx = GlobalContext("", buffer_create("", cursor), cursor)
|
||||
else:
|
||||
text = load_file(sys.argv[1])
|
||||
ctx = GlobalContext(text, buffer_create(text, sys.argv[1], cursor), cursor)
|
||||
from config import *
|
||||
from editing import *
|
||||
from keybindings import *
|
||||
@ -124,15 +131,15 @@ def main():
|
||||
keymap.mapping[kb_to_test]()
|
||||
if not keymap.pinned:
|
||||
keymap_stack.pop()
|
||||
break
|
||||
passthrough = False
|
||||
break
|
||||
else:
|
||||
if keymap.pop_not_found:
|
||||
keymap_stack.pop()
|
||||
else:
|
||||
print(f"{kb_to_test} not found")
|
||||
if not keymap.fallthrough:
|
||||
passthrough = False
|
||||
if len(kb_to_test.key) == 1:
|
||||
print(f"{kb_to_test} not found")
|
||||
break
|
||||
# No keybinding found so send the directly to the buffer
|
||||
# I think emacs instead binds every key to a function that sends the
|
||||
|
@ -7,5 +7,10 @@
|
||||
* DONE Basic text editing functions
|
||||
* DONE Basic keybindings system
|
||||
* DONE Parse keymaps so config matches pygame keys
|
||||
* TODO Keymap precedence system
|
||||
* DONE Keymap fallthrough/precedence stacking
|
||||
* DONE Pass the file you want to edit as a command line argument
|
||||
* DONE Save buffer function with a keybinding
|
||||
* TODO Add reverse parsing of keymaps to show users what they're typing
|
||||
* TODO Add reverse parsing of keymaps to show users what they're typing
|
||||
|
||||
|
||||
|
@ -18,6 +18,7 @@ class Keymap:
|
||||
|
||||
global keymappings
|
||||
global keymap_stack
|
||||
global reverse_binding
|
||||
|
||||
def modsym_to_flag(sym: str):
|
||||
match sym:
|
||||
@ -88,11 +89,15 @@ keymap_stack = [
|
||||
keymappings = {
|
||||
'insert': keymap_stack[0],
|
||||
'normal': keymap_stack[1],
|
||||
}
|
||||
}
|
||||
|
||||
# Do we even need this?
|
||||
reverse_binding = {}
|
||||
|
||||
def kb(mode: str, binding: str, f: Callable):
|
||||
b = parse_keybinding(binding)
|
||||
keymappings[mode].mapping[b] = f
|
||||
keybinding = parse_keybinding(binding)
|
||||
keymappings[mode].mapping[keybinding] = f
|
||||
reverse_binding[keybinding] = binding
|
||||
|
||||
def keymap_push(keymap: Keymap):
|
||||
keymap_stack.append(keymap)
|
||||
|
Loading…
x
Reference in New Issue
Block a user