Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2aa0ece
Merge sprint 22
aldum Dec 28, 2025
d295af0
feat: wiki
aldum Dec 12, 2025
32de736
fix(print): properly iterate nil args #99
aldum Dec 12, 2025
1836911
feat: run() restarts project in inspect mode #101
aldum Dec 12, 2025
9719aab
fix(debug): tweak table dumpers formatting
aldum Dec 12, 2025
5f3fdc2
test: disambiguate snippets
aldum Dec 12, 2025
8f3db21
test: move code setups to `it` blocks
aldum Dec 12, 2025
7f643a5
refactor(test): clean unused
aldum Dec 12, 2025
743f82e
chore: format just task
aldum Dec 12, 2025
5ae4ce5
feat: bump metalua
aldum Jan 9, 2026
6bc4a06
test: add a comment case to chunker suite
aldum Jan 12, 2026
898ae68
style(parser): add comment to inline function
aldum Jan 12, 2026
eb56c02
refactor: move CPos to metalua
aldum Jan 12, 2026
2cc22b1
fix(uim): has_error
aldum Jan 13, 2026
c62c752
refactor: pass CC into all controller functions
aldum Jan 13, 2026
ea8df1f
fix(cc): disallow edit when no project is open
aldum Jan 13, 2026
8692ea1
feat(cc): use_canvas()
aldum Jan 13, 2026
eed8d55
refactor(cc): use use_canvas() in run_user_code
aldum Jan 13, 2026
0e374fb
feat(c): use_canvas in event handlers
aldum Jan 13, 2026
e92255d
fix(buffer): extra line on moving down
aldum Jan 13, 2026
00c1ee1
fix: set default color to black #104
aldum Jan 13, 2026
a253416
style: remove stray comments
aldum Jan 13, 2026
ae63dee
chore(ci): cancel concurrent builds
aldum Jan 13, 2026
7807050
fix(test): editor spec
aldum Jan 13, 2026
e1dc5c0
fix(tixy): bit include
aldum Jan 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ env:
jobs:
run-busted:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.sha }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v4
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
dist/*
web/dist/*
web/dist-c/*
web/wiki/*
web/node_modules/*
.debug/*
doc/scratch/
Expand Down
4 changes: 2 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ unit_test_brief:
@{{MON}} -e 'lua' --exec 'echo -en "\n\n\n\n------------- BUSTED -------------\n"; busted tests -o tests/brief_output.lua'
unit_test_tag TAG:
@{{MON}} -e lua \
--exec 'echo -en "\n\n\n\n------------- BUSTED -------------\n" ; busted tests --defer-print --tags {{TAG}}'
--exec 'echo -en "\n\n\n\n------------- BUSTED -------------\n" ; busted tests --defer-print --tags="{{TAG}}"'
unit_test_ast:
@SHOW_AST=1 just unit_test_tag ast
@just unit_test_tag ast
unit_test_src:
@SHOW_CODE=1 just unit_test_tag src
unit_test_parser:
Expand Down
50 changes: 33 additions & 17 deletions src/controller/consoleController.lua
Original file line number Diff line number Diff line change
Expand Up @@ -98,25 +98,24 @@ end
--- @return boolean success
--- @return string? errmsg
local function run_user_code(f, cc, project_path)
local gfx = love.graphics
local output = cc.model.output
local env = cc:get_base_env()

gfx.setCanvas(cc:get_canvas())
local ok, call_err
if project_path then
env = cc:get_project_env()
end
ok, call_err = pcall(f)
if project_path and ok then -- user project exec
if love.PROFILE then
love.PROFILE.frame = 0
love.PROFILE.report = {}
cc:use_canvas(function()
if project_path then
env = cc:get_project_env()
end
cc.main_ctrl.set_user_handlers(env['love'])
end
output:restore_main()
gfx.setCanvas()
ok, call_err = pcall(f)
if project_path and ok then -- user project exec
if love.PROFILE then
love.PROFILE.frame = 0
love.PROFILE.report = {}
end
cc.main_ctrl.set_user_handlers(env['love'], cc)
end
output:restore_main()
end)
if not ok then
local msg = LANG.get_call_error(call_err)
return false, msg
Expand Down Expand Up @@ -429,12 +428,19 @@ function ConsoleController.prepare_project_env(cc)
project_env.stop = function()
cc:stop_project_run()
end
project_env.run = function()
if love.state.app_state == 'inspect' then
cc:stop_project_run()
cc:run_project()
end
end
project_env.run_project = project_env.run

project_env.continue = function()
if love.state.app_state == 'inspect' then
-- resume
love.state.app_state = 'running'
cc.main_ctrl.restore_user_handlers()
cc.main_ctrl.restore_user_handlers(cc)
else
print('No project halted')
end
Expand Down Expand Up @@ -766,8 +772,9 @@ end
function ConsoleController:edit(name, state)
if love.state.app_state == 'running' then return end

local PS = self.model.projects
local p = PS.current
local PS = self.model.projects
local p = PS.current
if not p then return end
local filename
-- if state and state.buffer then
-- filename = state.buffer.filename
Expand Down Expand Up @@ -1048,6 +1055,15 @@ function ConsoleController:get_canvas()
return self.model.output.canvas
end

--- @param f function
function ConsoleController:use_canvas(f)
local canvas = self.model.output.canvas
gfx.setCanvas(canvas)
local r = f()
gfx.setCanvas()
return r
end

--- @return ViewData
function ConsoleController:get_viewdata()
return {
Expand Down
43 changes: 24 additions & 19 deletions src/controller/controller.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,27 +43,27 @@ local _supported = {
'touchreleased',
}

local _C, _mode

--- @param C ConsoleController
--- @param msg string
local function user_error_handler(msg)
local function user_error_handler(C, msg)
Log.debug('user error: ' .. msg)
local err = LANG.get_call_error(msg) or ''
local user_msg = messages.exec_error(err)
_C:suspend_run(user_msg)
C:suspend_run(user_msg)
print(user_msg)
end

--- @param f function
--- @param C ConsoleController
--- @param ... any
--- @return boolean success
--- @return any result
--- @return any ...
local function wrap(f, ...)
local function wrap(f, C, ...)
if _G.web then
local ok, r = pcall(f, ...)
if not ok then
user_error_handler(r)
user_error_handler(C, r)
end
return r
else
Expand All @@ -72,22 +72,29 @@ local function wrap(f, ...)
end

--- @param f function
--- @param C ConsoleController
--- @return function
local function error_wrapper(f)
local function error_wrapper(f, C)
return function(...)
return wrap(f, ...)
local args = { ... }
C:use_canvas(
function()
return wrap(f, C, unpack(args))
end
)
end
end

--- @param userlove table
local set_handlers = function(userlove)
--- @param C ConsoleController
local set_handlers = function(userlove, C)
--- @param key string
local function hook_if_differs(key)
local orig = Controller._defaults[key]
local new = userlove[key]
if orig and new and orig ~= new then
--- @type function
love[key] = error_wrapper(new)
love[key] = error_wrapper(new, C)
end
end

Expand Down Expand Up @@ -384,7 +391,7 @@ Controller = {
local draw = function()
if ldr then
gfx.push('all')
wrap(ldr)
wrap(ldr, C)
gfx.pop()
end
local ui = get_user_input()
Expand All @@ -401,7 +408,9 @@ Controller = {
local uup = Controller._userhandlers.update
if user_update and uup
then
wrap(uup, dt)
C:use_canvas(function()
wrap(uup, C, dt)
end)
end
if love.state.app_state == 'snapshot' then
gfx.captureScreenshot(function(img)
Expand Down Expand Up @@ -477,11 +486,6 @@ Controller = {
----------------
--- public ---
----------------
--- @param CC ConsoleController
init = function(CC, mode)
_C = CC
_mode = mode
end,
--- @param C ConsoleController
--- @param CV ConsoleView
set_default_handlers = function(C, CV)
Expand Down Expand Up @@ -804,8 +808,9 @@ Controller = {
save_if_differs('draw')
end,

restore_user_handlers = function()
set_handlers(Controller._userhandlers)
--- @param C ConsoleController
restore_user_handlers = function(C)
set_handlers(Controller._userhandlers, C)
end,

clear_user_handlers = function()
Expand Down
2 changes: 1 addition & 1 deletion src/examples/tixy/mathlib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function hypot(a, b)
return math.sqrt(a ^ 2 + b ^ 2)
end

require("bit")
local bit = require("bit")
for k, v in pairs(bit or {}) do
_G[k] = v
end
2 changes: 1 addition & 1 deletion src/lib/metalua
3 changes: 2 additions & 1 deletion src/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -353,10 +353,11 @@ function love.load()
local CC = ConsoleController(CM, ctrl)
local CV = ConsoleView(baseconf, CC)

ctrl.init(CC, mode)
ctrl.setup_callback_handlers(CC)
ctrl.set_default_handlers(CC, CV)

gfx.setColor(0, 0, 0, 1)

if playback then
local ok, err = CC:open_project('play', true)
if not ok then
Expand Down
2 changes: 1 addition & 1 deletion src/model/editor/bufferModel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ function BufferModel:move_selection(dir, by, warp, move)
end
end
if dir == 'down' then
if (cur + by) <= last then
if (cur + by) <= last + 1 then
self.selection = cur + by
return true
end
Expand Down
7 changes: 5 additions & 2 deletions src/model/input/userInputModel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ function UserInputModel:get_wrapped_error()
local we = string.wrap_array(
e,
self.visible.wrap_w)
table.insert(we, 1, 'Errors:')
table.insert(we, 1, 'Errors:')
return we
end
end
Expand All @@ -880,7 +880,10 @@ end

--- @return boolean
function UserInputModel:has_error()
return string.is_non_empty_string_array(self.error)
if self.error and #(self.error) > 0 then
return true
end
return false
end

--- @param eval Evaluator
Expand Down
8 changes: 4 additions & 4 deletions src/model/io/redirect.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ local function set_print(M)
local origPrint = _G.print
_G.orig_print = origPrint
local magicPrint = function(...)
local arg = { ... }
local out = ''
local l = #arg
for i, v in ipairs(arg) do
out = out .. tostring(v)
local l = select('#', ...)
local args = { ... }
for i = 1, l do
out = out .. tostring(args[i])
if i ~= l then out = out .. '\t' end
end
origPrint(out)
Expand Down
12 changes: 7 additions & 5 deletions src/model/lang/lua/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ require("util.dequeue")

--- @class luaAST : token

--- @alias CPos 'first'|'last'

--- @class Comment
--- @field text string
--- @field position CPos
--- @field position CommentPos
--- @field idf integer
--- @field idl integer
--- @field first Cursor
Expand Down Expand Up @@ -318,6 +316,10 @@ return function(lib)
local idx = 1 -- block number
local last = 0 -- last line number
local comment_ids = {}
--- Create chunk from comment text and pos
--- @param ctext str
--- @param c Comment
--- @param range Range
local add_comment_block = function(ctext, c, range)
ret:insert(
Chunk.new(ctext, range),
Expand All @@ -326,7 +328,7 @@ return function(lib)
comment_ids[c.idl] = true
end
--- @param comments Comment[]
--- @param pos CPos
--- @param pos CommentPos
local get_comments = function(comments, pos)
for _, c in ipairs(comments) do
-- Log.warn('c', c.position)
Expand Down Expand Up @@ -415,7 +417,7 @@ return function(lib)

if
ret:last().tag ~= 'empty' and (
--- no empty line at EOF
--- no empty line at EOF
not single
--- there is an empty line at the end
or single and (#string.lines(text) > last)
Expand Down
12 changes: 8 additions & 4 deletions src/util/debug.lua
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,13 @@ local function terse_ast(ast, skip_lineinfo, style)

if type(k) == 'table' then
res = res .. dent .. terse(k, omit, style) .. assign
elseif type(k) == 'number' and style == 'lua' then
-- skip index
res = res .. dent .. '[' .. k .. '] ' .. assign
elseif type(k) == 'number' then
if style == 'lua' then
-- skip index
res = res .. dent .. '[' .. k .. '] ' .. assign
elseif style == 'json5' then
res = res .. dent .. '"' .. k .. '"' .. assign
end
elseif type(k) == 'string'
and not string.forall(k, Char.is_ascii)
then
Expand Down Expand Up @@ -320,7 +324,7 @@ Debug = {
if type(t) == 'table' then
local start = math.max(1, skip or 0)
for i = start, #t do
local l = t[i] or ''
local l = tostring(t[i]) or ''
local line = (function()
if not no_ln then
return string.format("#%02d: %s\n", i, text(l))
Expand Down
2 changes: 2 additions & 0 deletions src/view/consoleView.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@ function ConsoleView:draw(terminal, canvas, snapshot)
self.editor:draw()
end

gfx.push('all')
if love.state.app_state == 'editor' then
drawEditor()
else
drawConsole()
end
gfx.pop()
end

function ConsoleView:draw_placeholder()
Expand Down
4 changes: 4 additions & 0 deletions src/view/editor/editorView.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@ function EditorView:draw()
local spec = mode == 'reorder'
local bv = self:get_current_buffer()

gfx.push('all')
if ViewUtils.conditional_draw('show_buffer') then
bv:draw(spec)
end
if ViewUtils.conditional_draw('show_input') then
gfx.push('all')
self.input:draw()
gfx.pop()
end
gfx.pop()
end
end

Expand Down
Loading
Loading