incorporated the repl code

This commit is contained in:
Luxferre
2025-12-22 16:49:57 +02:00
parent 122bc06e7f
commit 93fddeff61
5 changed files with 326 additions and 4 deletions
+4 -3
View File
@@ -12,13 +12,14 @@ On T-Deck (Plus), the following components must be installed:
- CircuitPython 10.x (tested on 10.0.3);
- Adafruit Library Bundles from the [official CircuitPython page](https://circuitpython.org/libraries);
- [tdeck_repl](https://github.com/RetiredWizard/tdeck_repl) installed and set to boot on startup.
The [tdeck_repl](https://github.com/RetiredWizard/tdeck_repl) distribution is already incorporated into the repo.
On other generic platforms, most modules which are not T-Deck-specific are set to work on both CPython and MicroPython.
## Installation on T-Deck (Plus)
Current installation process doesn't involve any `.mpy` module compilation, so, after installing the prerequisites, you just need to copy the `deck` and `app` directories (and optionally the `tdeckboot.py` file, see the FAQ) into the root of the `CIRCUITPY` removable volume.
Current installation process doesn't involve any `.mpy` module compilation, so, after installing the prerequisites, you just need to copy the `repl`, `deck` and `app` directories, as well as the `code.py` and `tdeckboot.py` files, into the root of the `CIRCUITPY` removable volume.
## Components (`deck.*`)
@@ -214,7 +215,7 @@ No, but it provides comparable functionality to the on-device Python REPL. You c
It may at some point, but the entire idea is to give you the foundation to easily create your own custom shells for any special purposes. The project carries the spirit of early personal computing days when the programming language REPL (BASIC, Forth, Lisp etc) **was** your primary operating environment. In this case, the on-device Python REPL is such an environment.
To get a hang of how the shell **might** look like, you can run `from tdeckboot import *`. This will expose all the common methods from the main core modules. See the [tdeckboot.py](./tdeckboot.py) file for details.
To get the hang of what the shell **might** look like, you can already access some of the common methods from the main core modules via T-DeckARD REPL. See the [tdeckboot.py](./tdeckboot.py) file for details.
### Which platforms is T-DeckARD being tested on?
+35
View File
@@ -0,0 +1,35 @@
import os
try:
from repl.tdeck_repl import input
from repl.keys import show_keys
except:
pass
try:
from codeop import compile_command
except:
pass
if 'tdeckboot.py' in os.listdir('/'):
from tdeckboot import *
if 'autoexec.py' in os.listdir('/'):
import autoexec
print("T-DeckARD REPL ready")
__cmd = ""
while True:
__line = input(",,, " if __cmd else "=>> " )
if __cmd:
__cmd += ("\n" + (" " if __line != "" else "") + __line)
else:
if __line.lower() == 'exit': break
__cmd = __line
try:
if compile_command(__cmd):
exec(compile_command(__cmd))
__cmd = ""
except Exception as __err:
print("*ERROR* Exception:",str(__err))
__cmd = ""
+1 -1
View File
@@ -4,7 +4,7 @@
# init the tdeck_repl input where applicable
try:
from tdeck_repl import input
from repl.tdeck_repl import input
except:
pass
+17
View File
@@ -0,0 +1,17 @@
def show_keys():
print(" Entered Lilygo Keys Results")
print(" ------------------- -------")
print(" _- =")
print(" (+ [")
print(" +) ]")
print(" (- <")
print(" -) >")
print(" _# ^")
print(" _/ \\")
print(" -/ %")
print(" _! &")
print(" Speaker Key (left of enter) $")
print(" Track ball up up arrow")
print(" Track ball down down arrow")
print(" Track ball left left arrow")
print(" Track ball right right arrow")
+269
View File
@@ -0,0 +1,269 @@
from sys import stdin
import board
from supervisor import runtime
from adafruit_bus_device.i2c_device import I2CDevice
import keypad
import time
class PyDOS_UI:
def __init__(self):
self.trackevent = None
self.scrollable = False
self.arrow = ""
self._cmdhistlock = False
self._seqCnt = 0
self._key = bytearray(1)
self._touched = False
_ADDRESS_KBD = 0x55
self.commandHistory = [""]
self._i2c = I2CDevice(board.I2C(), _ADDRESS_KBD)
self.trackball = keypad.Keys(
[
board.TRACKBALL_CLICK,
board.TRACKBALL_UP,
board.TRACKBALL_DOWN,
board.TRACKBALL_LEFT,
board.TRACKBALL_RIGHT
],
value_when_pressed=False
)
def serial_bytes_available(self):
if not self._touched:
retval = 0
# Find the last direction the trackball was moved
# and wait for trackball to stop moving
self.arrow = ''
self.trackevent = Pydos_ui.trackball.events.get()
if self.trackevent and (self.trackevent.key_number not in [1,2] or not self._cmdhistlock):
self.arrow = ' ABDC'[self.trackevent.key_number]
if self.arrow == " ":
self.arrow = ""
else:
retval = 1
self._touched = True
if not self._touched:
with self._i2c as i2c:
try:
i2c.readinto(self._key)
except Exception as err:
self._key=bytearray(1)
if self._key[0] != 0:
retval = 1
self._touched = True
else:
retval = self.uart_bytes_available()
else:
retval = 1
return retval
def uart_bytes_available(self):
# Does the same function as supervisor.runtime.serial_bytes_available
retval = runtime.serial_bytes_available
return retval
def read_keyboard(self,num):
retval = ""
while num > 0:
self.serial_bytes_available()
if self._touched:
if self.arrow != "":
if self._seqCnt == 0:
retval += chr(27)
self._seqCnt = 1
num -= 1
elif self._seqCnt == 1:
retval += chr(91)
self._seqCnt = 2
num -= 1
elif self._seqCnt == 2:
retval += self.arrow
self._seqCnt = 0
self._touched = False
self.arrow = ""
num -= 1
else:
retval += chr(self._key[0])
self._touched = False
num -= 1
else:
if self.uart_bytes_available():
retval = stdin.read(num)
num -= len(retval)
return retval
Pydos_ui = PyDOS_UI()
def input(disp_text=None):
if disp_text != None:
print(disp_text,end="")
bld_chr1 = '_(+(-__-_'
bld_chr2 = '-+)-)/#/!'
bld_chr = '=[]<>\^%&'
bld_started = False
histPntr = len(Pydos_ui.commandHistory)
Pydos_ui._cmdhistlock = False
keys = ''
editCol = 0
loop = True
ctrlkeys = ''
arrow = ''
onLast = True
onFirst = True
blink = True
timer = time.time()
while loop:
#print(editCol,keys)
if ctrlkeys == '':
arrow = ""
else:
ctrlkeys = ''
if arrow == 'A' or arrow == 'B':
if len(Pydos_ui.commandHistory) > 0:
print(('\x08'*(editCol))+(" "*(len(keys)+1))+('\x08'*(len(keys)+1)),end="")
if arrow == 'A':
histPntr -= 1
else:
histPntr += 1
histPntr = histPntr % len(Pydos_ui.commandHistory)
print(Pydos_ui.commandHistory[histPntr],end="")
keys = Pydos_ui.commandHistory[histPntr]
editCol = len(keys)
if editCol == 0:
onFirst = True
else:
onFirst = False
elif arrow == 'D':
Pydos_ui._cmdhistlock = True
if len(keys) > editCol:
print(keys[editCol:editCol+1]+"\x08",end="")
elif editCol == len(keys):
print(" \x08",end="")
editCol = max(0,editCol-1)
if editCol > 0:
print('\x08',end="")
onLast = False
elif editCol == 0:
if not onFirst:
print('\x08',end="")
onFirst = True
elif arrow == 'C':
if len(keys) > editCol:
print(keys[editCol:editCol+1]+"\x08",end="")
editCol += 1
editCol = min(len(keys),editCol)
if editCol < len(keys):
print(keys[editCol-1:editCol],end="")
onFirst = False
elif editCol == len(keys):
if not onLast:
print(keys[editCol-1:],end="")
onLast = True
Pydos_ui._cmdhistlock = False
if Pydos_ui.serial_bytes_available():
if Pydos_ui.uart_bytes_available():
keys = keys[:editCol]+stdin.read(1)+keys[editCol:]
else:
keys = keys[:editCol]+Pydos_ui.read_keyboard(1)+keys[editCol:]
editCol += 1
if keys[editCol-1] == '\x1b':
keys = keys[:editCol-1]+keys[editCol:]
if Pydos_ui.uart_bytes_available():
ctrlkeys = stdin.read(2)
else:
ctrlkeys = Pydos_ui.read_keyboard(2)
# ctrlkeys = up:[A down:[B right:[C left:[D
arrow = ctrlkeys[1]
# Convert two character sequences into missing keyboard keys
# '_-' -> '=' '(+' -> '[' '+)' -> ']'
bld_done = False
if bld_started:
bcindx = bld_chr2.find(keys[editCol-1:editCol])
nextbc = 0
while nextbc != -1 and bld_started:
if keys[editCol-2:editCol] == bld_chr1[bcindx]+bld_chr2[bcindx]:
bld_started = False
bld_done = True
keys = keys[:editCol-2]+bld_chr[bcindx]+keys[editCol:]
print('\x08'+keys[editCol-2:]+' '+('\x08'*(len(keys[editCol:])+(1 if onLast else 2))),end="")
editCol -= 1
else:
nextbc = bld_chr2[bcindx+1:].find(keys[editCol-1:editCol])
bcindx = bcindx + nextbc + 1
if bld_chr1.find(keys[editCol-1:editCol]) != -1 and arrow == "" and not bld_done:
bld_started = True
else:
bld_started = False
if arrow != "" and ctrlkeys != "":
editCol -= 1
elif arrow !='':
pass
elif keys[editCol-1:editCol] in ['\x08','\x7f']:
keys = keys[:max(0,editCol-2)]+keys[editCol:]
if editCol > 1:
print(('\x08'*(editCol-1))+keys+' \x08\x08',end="")
editCol = max(0,editCol-2)
if editCol < len(keys):
print("\x08"*(len(keys)-editCol),end="")
else:
editCol -= 1
onFirst = True
elif len(keys[editCol-1:editCol]) > 0 and keys[editCol-1:editCol] in '\n\r':
if len(keys) > editCol:
print(keys[editCol:editCol+1]+"\x08",end="")
elif editCol == len(keys):
print(" \x08",end="")
keys = keys[:editCol-1]+keys[editCol:]
if keys.strip() != "":
Pydos_ui.commandHistory.append(keys)
if len(Pydos_ui.commandHistory) > 10:
Pydos_ui.commandHistory.pop(1)
histPntr = len(Pydos_ui.commandHistory)
print()
loop = False
elif not bld_done:
onFirst = False
print(keys[editCol-1:],end="")
if len(keys[editCol-1:]) > 1:
print(" \x08",end="")
if editCol < len(keys):
print("\x08"*(len(keys)-editCol),end="")
if loop:
if time.time() != timer:
blink = not blink
timer = time.time()
if blink:
print("_\x08",end="")
else:
if len(keys) > editCol:
print(keys[editCol:editCol+1]+"\x08",end="")
else:
print(" \x08",end="")
return keys