added getcursor pos, undone forced fullscreen

This commit is contained in:
Art 2022-12-29 15:54:08 +01:00
parent 4e1ee4d089
commit a013c34fc4
Signed by: prod2
GPG Key ID: F3BB5A97A70A8DDE
8 changed files with 93 additions and 44 deletions

BIN
editor Executable file

Binary file not shown.

View File

@ -1,12 +1,11 @@
import unicode
import strutils
import terminal
import strformat
import posix
import termBuffer/buffer
import keycodes
import terminalUtils/buffer
import terminalUtils/terminalGetInfo
import terminalUtils/keycodes
type
EditorState* = ref object
@ -44,7 +43,6 @@ proc newEditor*(prompt: string = "> ", multiline: bool = true): EditorState =
result.prompt = prompt
result.maxRowsGoal = if multiline: 0 else: 1
result.buffer.add("")
result.screenBuffer = newBuffer(0, 0, terminalWidth(), terminalHeight(), stdout)
editors.add(result)
proc destroyEditor*(oldEditor: EditorState) =
@ -63,13 +61,11 @@ proc render(ed: EditorState) =
template cline(ed: EditorState): var string =
ed.buffer[ed.y]
proc print*(ed: EditorState, text: string) =
ed.screenBuffer.print(text)
ed.screenBuffer.redraw()
proc read*(ed: EditorState): (EditorResult, string) =
var editorResult = erError
let (_, cursorY) = termGetCursorPos(stdout)
ed.screenBuffer = newBuffer(0, cursorY, termGetWidth(), termGetHeight() - cursorY, stdout)
ed.render()
while true:
@ -126,8 +122,10 @@ proc read*(ed: EditorState): (EditorResult, string) =
result = (editorResult, ed.buffer.join("\n"))
# cleanup
stdout.write("\n")
ed.history.add(ed.buffer)
ed.buffer = @[""]
ed.y = 0
ed.x = 0
ed.screenBuffer = nil

View File

@ -1,10 +1,10 @@
import editor
let e = newEditor("> ", false)
let e = newEditor(">>> ", false)
while true:
let (res, text) = e.read()
if res in {erCtrlC, erCtrlD} or text == "quit":
e.print("")
break
e.print(text)
if text.len() > 0:
echo text

View File

@ -1,14 +0,0 @@
# list of functions to generate escape sequences
import strformat
import strutils
func escCursorPos*(x, y: int): string =
&"\e[{y+1};{x+1}H"
func escAttributes*(attributes: seq[uint8]): string =
let joined = attributes.join(";")
&"\e[{joined}m"
func escEraseCharacters*(n: int): string =
&"\e[{n}X"

View File

@ -100,22 +100,7 @@ proc write*(buf: Buffer, text: string) =
for i in fromPos..toPos:
buf.buffered[i] = Cell(text: runes[i-fromPos], attributes: buf.cursorAttributes)
buf.bufferX += runes.len()
proc print*(buf: Buffer, text: string) =
# write, but makes sure it's on its own line
if buf.bufferX > 0:
# TODO scroll implementation
buf.bufferX = 0
if buf.bufferY < buf.height - 1:
buf.bufferY += 1
buf.write(text)
# TODO scroll implementation
if text.len() > 0 and buf.bufferY < buf.height - 1:
buf.bufferY += 1
buf.bufferX += runes.len()
proc redraw*(buf: Buffer, force: bool = false) =
var toPrint = ""
@ -130,7 +115,7 @@ proc redraw*(buf: Buffer, force: bool = false) =
let y = i div buf.width
let x = i mod buf.width
# go to given place
toPrint &= escCursorPos(x+buf.positionX, y+buf.positionY)
toPrint &= escSetCursorPos(x+buf.positionX, y+buf.positionY)
# get the right attributes
# first reset
@ -149,7 +134,7 @@ proc redraw*(buf: Buffer, force: bool = false) =
# finish
toPrint &= escAttributes(@[fsReset.uint8])
toPrint &= escCursorPos(buf.bufferX + buf.positionX, buf.bufferY + buf.positionY)
toPrint &= escSetCursorPos(buf.bufferX + buf.positionX, buf.bufferY + buf.positionY)
buf.stdout.write(toPrint)
@ -157,6 +142,7 @@ func getSize*(buf: Buffer): (int, int) =
(buf.width, buf.height)
proc resize*(buf: Buffer, newX, newY: int) =
# TODO
raise newException(Defect, "Not implemented")
func getPosition*(buf: Buffer): (int, int) =

View File

@ -0,0 +1,45 @@
# list of functions to generate escape sequences
# in the future, this can be expanded to support more platforms
import strformat
import strutils
import terminal
func escSetCursorPos*(x, y: int): string =
&"\e[{y+1};{x+1}H"
const escGetCursorPos* = "\e[6n"
type InvalidResponseError* = object of CatchableError
proc termGetCursorPos*(ouput: File): (int, int) =
ouput.write(escGetCursorPos)
var response = ""
if getch() != '\e':
raise newException(InvalidResponseError, "Unsupported terminal - can't get cursor position.")
if getch() != '[':
raise newException(InvalidResponseError, "Can't parse response in getCursorPos")
var newChar = getch()
while newChar != ';':
response &= newChar
newChar = getch()
let y = parseInt(response) - 1
response = ""
newChar = getch()
while newChar != 'R':
response &= newChar
newChar = getch()
let x = parseInt(response) - 1
return (x, y)
func escAttributes*(attributes: seq[uint8]): string =
let joined = attributes.join(";")
&"\e[{joined}m"
func escEraseCharacters*(n: int): string =
&"\e[{n}X"

View File

@ -0,0 +1,34 @@
import terminal
import strutils
import escapeSequences
proc termGetCursorPos*(ouput: File): (int, int) =
ouput.write(escGetCursorPos)
var response = ""
if getch() != '\e':
raise newException(InvalidResponseError, "Unsupported terminal - can't get cursor position.")
if getch() != '[':
raise newException(InvalidResponseError, "Can't parse response in getCursorPos")
var newChar = getch()
while newChar != ';':
response &= newChar
newChar = getch()
let y = parseInt(response) - 1
response = ""
newChar = getch()
while newChar != 'R':
response &= newChar
newChar = getch()
let x = parseInt(response) - 1
return (x, y)
proc termGetWidth*: int =
terminalWidth()
proc termGetHeight*: int =
terminalHeight()