Even more line editing improvements

This commit is contained in:
20kdc 2020-03-30 14:36:33 +01:00
parent 479412a5bb
commit 339571ee9b
8 changed files with 183 additions and 11 deletions

View File

@ -24,7 +24,7 @@ return {
},
["neo-docs"] = {
desc = "KittenOS NEO system documentation",
v = 8,
v = 9,
deps = {
"zzz-license-pd"
},
@ -43,6 +43,7 @@ return {
"docs/us-setti",
"docs/us-evrst",
"docs/us-clawf",
"docs/us-termi",
"docs/ul-seria",
"docs/ul-fwrap",
"docs/ul-event",
@ -50,6 +51,7 @@ return {
"docs/ul-neoux",
"docs/ul-brail",
"docs/ul-bmp__",
"docs/ul-linee",
"docs/gp-pedan",
"docs/repoauthors/neo-docs"
},

View File

@ -131,7 +131,7 @@ local function getline(y)
return ("¬"):rep(sW)
end
line = unicode.safeTextFormat(line)
return lineEdit.draw(sW, line, cursorXP, rY == cursorY, rX)
return lineEdit.draw(sW, line, rY == cursorY and cursorXP, rX)
end
local function delLine()
local contents = lines[cursorY]
@ -268,7 +268,7 @@ local function key(ks, kc, down)
elseif lX == "l>" and cursorY < #lines then
cursorY = cursorY + 1
cursorX = 1
elseif lX == "wpl" and cursorY ~= 1 then
elseif lX == "w<" and cursorY ~= 1 then
local l = table.remove(lines, cursorY)
cursorY = cursorY - 1
cursorX = unicode.len(lines[cursorY]) + 1

View File

@ -43,8 +43,9 @@ local function fmtLine(s)
end
local function line(i)
local l = console[i] or l15
l = require("lineedit").draw(sW, l, cX, i == sH)
local l, c = console[i] or l15
l, c = unicode.safeTextFormat(l, cX)
l = require("lineedit").draw(sW, l, i == sH and c)
if i ~= sH then
window.span(1, i, l, 0xFFFFFF, 0)
else

View File

@ -3,13 +3,13 @@
return {
-- note: everything must already be unicode.safeTextFormat'd
draw = function (sW, line, cursorX, cursorOn, rX)
draw = function (sW, line, cursorX, rX)
-- if no camera, provide a default
rX = rX or math.max(1, cursorX - math.floor(sW * 2 / 3))
rX = rX or math.max(1, (cursorX or 1) - math.floor(sW * 2 / 3))
-- transform into area-relative
local tl = unicode.sub(line, rX, rX + sW - 1)
-- inject cursor
if cursorOn then
if cursorX then
cursorX = (cursorX - rX) + 1
if cursorX >= 1 then
if cursorX <= sW then
@ -51,8 +51,8 @@ return {
return nil, unicode.len(line) + 1
elseif ks == "\8" or kc == 211 then -- del
if cursorX == 1 then
-- weld prev line
return nil, nil, "wpl"
-- weld prev
return nil, nil, "w<"
else
cS = unicode.sub(cS, 1, unicode.len(cS) - 1)
return cS .. cE, cursorX - 1

View File

@ -383,7 +383,7 @@ newNeoux = function (event, neo)
local t, e, r = textprop(), require("lineedit")
p = e.clamp(t, p)
t, r = unicode.safeTextFormat(t, p)
window.span(x, y, "[" .. e.draw(w - 2, t, r, selected) .. "]", bg, fg)
window.span(x, y, "[" .. e.draw(w - 2, t, selected and r) .. "]", bg, fg)
end
}
end

View File

@ -16,4 +16,6 @@ repository/docs/us-nxapp: 20kdc, Public Domain
repository/docs/us-perms: 20kdc, Public Domain
repository/docs/us-setti: 20kdc, Public Domain
repository/docs/us-clawf: 20kdc, Public Domain
repository/docs/ul-linee: 20kdc, Public Domain
repository/docs/us-termi: 20kdc, Public Domain

74
repository/docs/ul-linee Normal file
View File

@ -0,0 +1,74 @@
The "lineedit" library provides a
quick way to implement nice line
editing into applications.
It requires the user to store the
line and the cursor position for the
line, which allows the user to
implement any additional logic for
the application.
(To clarify, this implies that the
library's functions are stateless.)
The functions are as follows:
draw = function (sW, line, curX, rX):
Returns the spantext.
sW is the width of the area.
line is the safeTextFormatted text.
curX is the cursor in screen units
(usually done as part of the text
formatting)
This is optional, and if not provided
the cursor will not be shown.
rX is an optional camera override.
If not provided, the cursor will be
used; if that is not provided, then
the left side will be shown.
clamp = function (line, curX):
Returns curX clamped to the line's
length (does not check for < 1).
key = function (ks, kc, line, curX):
Performs something.
ks, if truthy, is the unicode.char
of the key event key character.
kc is the key event keycode.
(If feeding in clipboard characters,
use 0 here.)
line is the text.
This returns three values, any of
which or all of which may be nil for
a 'no effect' response:
The new line text, 'lT'.
The new curX, 'lC'.
The extended action, 'lX'.
The following extended actions exist:
"l<": The cursor should be warped to
the end of the previous line, if one
exists (if not, do nothing)
"l>": The cursor should be warped to
the start of the next line, if one
exists (if not, do nothing)
"w<": This line should be welded to
the previous line, and the cursor
should be placed at the weld point.
"nl": The Enter button was pressed.
-- This is released into
the public domain.
-- No warranty is provided,
implied or otherwise.

93
repository/docs/us-termi Normal file
View File

@ -0,0 +1,93 @@
The "svc-t" program / "x.svc.t"
permission makes up the terminal
subsystem for KittenOS NEO.
--- THEORETICAL TERMINALS MODEL ---
The theoretical model for terminals
in KittenOS NEO is that of a stack
of processes controlling a player's
connection to a MUD, where text is
provided to the server and to the
player in a line-by-line format,
with no "flow control"/ttyattrs.
A process starting another process
connected to the same terminal is
advised to wait for that process to
die before continuing in terminal
activities, unless some sort of
'in-band notification' functionality
is intended.
The controlling process is whichever
process is supposed to be accepting
user input. This is contextual, and
there is no mechanism to control
this explicitly.
The controlling process should show
text in response to any user input,
or at least provide some form of
acknowledgement that user input has
been received.
User input IS NOT automatically
echoed by the terminal.
--- ACTUAL USAGE OF TERMINALS ---
Access control on terminals is looser
than for most permissions, as it has
to be able to be 'sublet' in some
cases, including events.
A terminal program is given a string
argument for the ID of the terminal
to connect to.
A terminal always has an ID beginning
with "x.svc.t/". ALWAYS CHECK THIS.
Requiring the responsible access
connects to the terminal. All
terminal programs SHOULD check for
the death of their parent terminal
(via the k.procdie event) and
self-destruct accordingly.
A program may start svc-t directly.
In this case, it must pass a function
(resTbl) and may pass a title.
When the terminal has shown, the
function provided is called with a
table as follows:
access = "x.svc.t/<...>"
close = function (): close terminal
The k.kill permission and the close
function are the only ways for a
program to kill a terminal, and the
close function is only given to the
creating process.
In either case, when the access has
been acquired, the following API is
presented:
id = "x.svc.t/<...>"
pid = <The terminal's PID.>
line = function (text): Shows a line.
When the user sends a line, an event
of: <id>, "line", <text>
is provided.
-- This is released into
the public domain.
-- No warranty is provided,
implied or otherwise.