Add picker, refine things

This commit is contained in:
Jeff Epler 2023-07-05 14:35:58 -05:00
parent 511cd81acb
commit 74d64c9a47
No known key found for this signature in database
GPG key ID: D5BF15AB975AB4DE
4 changed files with 78 additions and 9 deletions

View file

@ -1,5 +1,6 @@
import editor
import picker, editor
try:
editor.edit("code.py")
filename = picker.pick_file()
editor.edit(filename)
except KeyboardInterrupt:
pass

View file

@ -98,7 +98,7 @@ def wrapper(func, *args, **kwds):
stdscr = Screen()
try:
_nonblocking()
func(stdscr, *args, **kwds)
return func(stdscr, *args, **kwds)
finally:
_blocking()
stdscr.move(LINES-1, 0)

View file

@ -1,4 +1,5 @@
import dang as curses
import os
import sys
import gc
@ -20,6 +21,13 @@ class MaybeDisableReload:
runtime.autoreload = self._old_autoreload
def os_exists(filename):
try:
os.stat(filename)
return True
except OSError:
return False
def gc_mem_free_hint():
if hasattr(gc, 'mem_free'):
gc.collect()
@ -172,15 +180,18 @@ def end(window, buffer, cursor):
window.horizontal_scroll(cursor)
def editor(stdscr, filename):
with open(filename) as f:
buffer = Buffer(f.read().splitlines())
if os_exists(filename):
with open(filename) as f:
buffer = Buffer(f.read().splitlines())
else:
buffer = Buffer([])
window = Window(curses.LINES - 1, curses.COLS - 1)
cursor = Cursor()
stdscr.erase()
img = [''] * window.n_rows
img = [''] * curses.LINES
def setline(row, line):
if img[row] == line:
return
@ -188,7 +199,7 @@ def editor(stdscr, filename):
stdscr.addstr(row, 0, line)
while True:
for row, line in enumerate(buffer[window.row:window.row + window.n_rows-1]):
for row, line in enumerate(buffer[window.row:window.row + window.n_rows]):
if row == cursor.row - window.row and window.col > 0:
line = "«" + line[window.col + 1:]
if len(line) > window.n_cols:
@ -196,7 +207,7 @@ def editor(stdscr, filename):
line += ' ' * (window.n_cols - len(line))
setline(row, line)
row = window.n_rows - 1
row = curses.LINES - 1
if readonly():
line = f"{filename:12} (readonly) | ^C: quit{gc_mem_free_hint()}"
else:
@ -243,7 +254,7 @@ def editor(stdscr, filename):
def edit(filename):
with MaybeDisableReload():
curses.wrapper(editor, filename)
return curses.wrapper(editor, filename)
if __name__ == "__main__":
import argparse

57
picker.py Normal file
View file

@ -0,0 +1,57 @@
import os
import dang as curses
always = ["code.py", "boot.py", "settings.toml", "boot_out.txt"]
good_extensions = [".py", ".toml", ".txt", ".json"]
def os_exists(filename):
try:
os.stat(filename)
return True
except OSError:
return False
def isdir(filename):
return os.stat(filename)[0] & 0o40_000
def has_good_extension(filename):
for g in good_extensions:
if filename.endswith(g):
return True
return False
def picker(stdscr, options, notes=[], start_idx=0):
stdscr.erase()
stdscr.addstr(curses.LINES-1, 0, "Enter: select | ^C: quit")
del options[curses.LINES-1:]
for row, option in enumerate(options):
if row < len(notes) and (note := notes[row]):
option = f"{option} {note}"
stdscr.addstr(row, 3, option)
old_idx = None
idx = start_idx
while True:
if idx != old_idx:
if old_idx is not None:
stdscr.addstr(old_idx, 0, " ")
stdscr.addstr(idx, 0, "=>")
old_idx = idx
k = stdscr.getkey()
if k == 'KEY_DOWN':
idx = min(idx + 1, len(options) - 1)
elif k == 'KEY_UP':
idx = max(idx - 1, 0)
elif k == '\n':
return options[idx]
def pick_file():
options = always[:] + sorted(
(g for g in os.listdir('.') if g not in always and not isdir(g) and not g.startswith('.')),
key=lambda filename: (not has_good_extension(filename), filename),
)
notes = [None if os_exists(filename) else "(NEW)" for filename in options]
return curses.wrapper(picker, options, notes)