Skip to content

Commit

Permalink
fix docs, merging modules
Browse files Browse the repository at this point in the history
  • Loading branch information
Tieske committed Jun 3, 2024
1 parent 56db151 commit 3a6597d
Show file tree
Hide file tree
Showing 7 changed files with 384 additions and 67 deletions.
1 change: 1 addition & 0 deletions config.ld
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ dir='docs'
sort=true
sort_modules=true
all=false
merge=true
323 changes: 310 additions & 13 deletions examples/readline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ readline.__index = readline
--- Create a new readline object.
-- @tparam table opts the options for the readline object
-- @tparam[opt=""] string opts.prompt the prompt to display
-- @tparam[opt=""] string opts.prompt_format the prompt format (ansi sequence colorization etc)
-- @tparam[opt=""] string opts.box_format the box format (ansi sequence colorization etc)
-- @tparam[opt=80] number opts.max_length the maximum length of the input (in characters, not bytes)
-- @tparam[opt=""] string opts.value the default value
-- @tparam[opt=`#value`] number opts.position of the cursor in the input
Expand Down Expand Up @@ -175,6 +177,8 @@ function readline.new(opts)
position = pos, -- the current position in the input
drawn_before = false, -- if the prompt has been drawn
exit_keys = exit_keys, -- the keys that will cause the readline to exit
prompt_format = opts.prompt_format or "",
box_format = opts.box_format or "",
}

setmetatable(self, readline)
Expand All @@ -193,7 +197,7 @@ local function draw(self, redraw)
io.write(cursor_move_horiz(-(#self.prompt + self.position)))
end
-- write prompt & value
io.write(tostring(self.prompt) .. tostring(self.value))
io.write(self.prompt_format, tostring(self.prompt), self.box_format, tostring(self.value))
-- clear remainder of input size
io.write(string.rep(" ", self.max_length - self.value.chars))
io.write(cursor_move_horiz(-(self.max_length - self.value.chars)))
Expand Down Expand Up @@ -434,8 +438,228 @@ end
-- return readline -- normally we'd return here, but for the example we continue


local function savePos()
return "\27[s"
end

local function restorePos()
return "\27[u"
end

local function curLeft(n)
return "\27[" .. (n or 1) .. "D"
end

local function curRight(n)
return "\27[" .. (n or 1) .. "C"
end

local function curUp(n)
return "\27[" .. (n or 1) .. "A"
end

local function curDown(n)
return "\27[" .. (n or 1) .. "B"
end

local function pos(row, col)
return string.format("\027[%d;%dH", row, col)
end


-- characters for drawing borders
local borderChars = {
double ={
top_left = "",
top_right = "",
bottom_left = "",
bottom_right = "",
vertical = "",
horizontal = "",
titleLeft = "",
titleRight = "",
},
single = {
top_left = "",
top_right = "",
bottom_left = "",
bottom_right = "",
vertical = "",
horizontal = "",
titleLeft = "",
titleRight = "",
},
}

-- draw left to right
local function hline(border, length)
return (borderChars[border].horizontal):rep(length)
end

-- draw top to bottom
local function vline(border, length)
return (borderChars[border].vertical .. curDown() .. curLeft()):rep(length)
end


local Window = {}
Window.__index = Window

Window.borders = {
single = "single"",
double = "double",
none = "none",
}

function Window.new(opts)
local r, c = sys.termsize()

local header
if type(opts.header) == "string" then
header = { left = "", mid = opts.header, right = ""}
elseif type(opts.header) == "table" then
header = {
left = opts.header.left or "",
mid = opts.header.mid or "",
right = opts.header.right or "",
}
end

local footer
if type(opts.footer) == "string" then
footer = { left = "", mid = opts.footer, right = ""}
elseif type(opts.footer) == "table" then
footer = {
left = opts.footer.left or "",
mid = opts.footer.mid or "",
right = opts.footer.right or "",
}
end

local self = {
pos = {
row = opts.row or 1,
col = opts.col or 1,
},
size = {
height = opts.height or (r - (opts.row or 1) + 1),
width = opts.width or (c - (opts.col or 1) + 1),
},
header = header,
footer = footer,
border = assert(Window.borders[opts.border or "single"], "invalid border option"),
}

self.title = self.border == "none" and opts.title or nil

self.cpos = {
row = self.pos.row + (self.border ~= "none" and 1 or 0) + (self.header and 1 or 0),
col = self.pos.col + (self.border ~= "none" and 1 or 0),
}
self.csize = {
height = self.size.height - (self.border ~= "none" and 2 or 0) - (self.header and 1 or 0) - (self.footer and 1 or 0),
width = self.size.width - (self.border ~= "none" and 2 or 0),
}
assert(self.csize.height > 0, "height too small")
assert(self.csize.width > 0, "width too small")

setmetatable(self, Window)
return self
end



-- draws the top-border of the window, with the title centered
-- (does not draw the 2 corners)
function Window:_drawTitle()
if self.border == "none" then
return
end

if not self._titleString then
local w = self.size.width - 2 --inner size
w = w - 2 -- edge lines

local t = self.title
if w < #t then
-- title doesn't fit
if w <= 3 then
t = ""
else
t = borderChars.titleLeft .. t:sub(1, w - 3) .. "..." .. borderChars.titleRight
end
else
t = borderChars.titleLeft .. t .. borderChars.titleRight
end
local lead = math.floor((w - #t) / 2)
local trail = w - #t - lead
local t ={
savePos(),
pos(self.pos.row, self.pos.col + 1),
borderChars[self.border].horizontal:rep(lead),
t,
borderChars[self.border].horizontal:rep(trail),
restorePos(),
}
self._titleString = table.concat(t)
end
io.stdout:write(self._titleString)
end

function Window:drawTitle()
self:_drawTitle()
io.stdout:flush()
end

function Window:setTitle(title)
if self.border == "none" then
return
end
self.title = title
self._titleString = nil
self:drawTitle()
end


-- draws the border of the window
function Window:_drawBorder()
if self.border == "none" then
return
end

if not self._borderString then
local t = {
savePos(),
pos(self.pos.row, self.pos.col),
borderChars[self.border].top_left,
curDown(),
curLeft(),
vline(self.border, self.size.height - 2),
borderChars[self.border].bottom_left,
hline(self.border, self.size.width - 2),
borderChars[self.border].bottom_right,
pos(self.pos.row, self.pos.col + self.size.width - 1),
borderChars[self.border].top_right,
vline(self.border, self.size.height - 2),
restorePos(),
}
self._borderString = table.concat(t)
end
io.stdout:write(self._borderString)
self:_drawTitle()
end

function Window:drawBorder()
self:_drawBorder()
io.stdout:flush()
end




function Window:draw(clear)
end

local backup = sys.termbackup()

-- setup Windows console to handle ANSI processing
Expand All @@ -452,20 +676,93 @@ sys.tcsetattr(io.stdin, sys.TCSANOW, {
sys.setnonblock(io.stdin, true)


local rl = readline.new{
prompt = "Enter something: ",
max_length = 60,
value = "Hello, 你-好 World 🚀!",
-- position = 2,
exit_keys = {key_sequences.enter, "\27", "\t", "\27[Z"}, -- enter, escape, tab, shift-tab
}


local result, key = rl()
print("") -- newline after input, to move cursor down from the input line
print("Result (string): '" .. result .. "'")
print("Result (bytes):", result:byte(1,-1))
print("Exit-Key (bytes):", key:byte(1,-1))
local copas = require "copas"

local cheader = "\027[48;2;47;79;79m\027[38;2;224;255;255m"
local cfooter = "\027[48;2;47;79;79m\027[38;2;224;255;255m"
local cbody = "\027[48;2;27;38;59m\027[38;2;248;248;255m"
local caccent1 = "\027[38;2;70;130;180m"
local caccent2 = "\027[38;2;176;196;222m"
local cinput = caccent1 .. "\027[48;2;10;22;34m"
local ctext = "\027[48;2;27;38;59m\027[38;2;211;211;211m"
local cerror = "\027[48;2;27;38;59m\027[38;2;205;92;92m"
local clrscr = "\027[2J"
local clreol = "\027[K"


local isExiting, timerCoro

-- formats time in HH:MM:SS, and prints it on the top left corner of the console.
-- stores cursor position before, and restores it after
local function timer()
do return end
while true do
copas.pause((math.floor(sys.gettime()) + 1) - sys.gettime())
if isExiting then return end
-- ansi to backup cursor position
io.write("\27[s")
-- ansi to hide cursor
io.write("\27[?25l")
-- ansi to move cursor to top left corner
io.write(pos(1,1), cheader)
-- get current time
local t = os.date("*t")
-- format time
io.write(("%02d:%02d:%02d"):format(t.hour, t.min, t.sec))
-- ansi to restore cursor position
io.write("\27[u")
-- ansi to show cursor
io.write("\27[?25h")
io.flush()
end
end

local function readdata()
local rl = readline.new{
prompt = "Enter something: ",
prompt_format = ctext,
box_format = cinput,
max_length = 60,
value = "Hello, 你-好 World 🚀!",
-- position = 2,
exit_keys = {key_sequences.enter, "\27", "\t", "\27[Z"}, -- enter, escape, tab, shift-tab
}


local result, key = rl()
print("") -- newline after input, to move cursor down from the input line
print("Result (string): '" .. result .. "'")
print("Result (bytes):", result:byte(1,-1))
print("Exit-Key (bytes):", key:byte(1,-1))
isExiting = true
copas.wakeup(timerCoro)
end


local function setup_screen()
local cols, rows = sys.termsize()
io.write(pos(1,1))
io.write(cheader, clreol, "xyz\n")
io.write(cbody, (clreol.."\n"):rep(rows-2))
io.write(cfooter, clreol, "x")
io.write(pos(10,1))
io.write(cbody)
io.flush()
end


copas(function()
sys.sleep = copas.sleep
isExiting = false
setup_screen()
copas.addthread(timer)
copas.addthread(readdata)
end)





-- Clean up afterwards
Expand Down
6 changes: 5 additions & 1 deletion src/environment.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
/// @submodule system
/// @module system

/// Environment.
// @section environment

#include <lua.h>
#include <lauxlib.h>
#include "compat.h"
Expand Down
7 changes: 6 additions & 1 deletion src/random.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
/// @submodule system
/// @module system

/// Random.
// @section random


#include <lua.h>
#include <lauxlib.h>
#include "compat.h"
Expand Down
5 changes: 4 additions & 1 deletion src/term.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/// @submodule system
/// @module system

/// Terminal.
// Unix: see https://blog.nelhage.com/2009/12/a-brief-introduction-to-termios-termios3-and-stty/
//
// Windows: see https://learn.microsoft.com/en-us/windows/console/console-reference
// @section terminal

#include <lua.h>
#include <lauxlib.h>
Expand Down
Loading

0 comments on commit 3a6597d

Please sign in to comment.