feat: add fullscreen TUI and project updates

- New TUI screens: Main Menu, Compile, Run, REPL, AI Generator, AI Settings, Help
- AI configuration persisted in ~/.config/cljnim/config.json
- Added illwill dependency for terminal UI
- Updated experiments, examples, docs, and core modules
This commit is contained in:
2026-05-09 01:53:23 +03:00
parent 2bc64eca22
commit ba0b300917
42 changed files with 3042 additions and 153 deletions
+15 -17
View File
@@ -46,7 +46,6 @@ proc expandSyntaxQuote*(form: CljVal): CljVal =
if head.symName == "unquote-splicing":
raise newException(CatchableError, "unquote-splicing can only be used inside a collection")
# Process each element
var result: seq[CljVal] = @[]
var parts: seq[CljVal] = @[]
for item in form.items:
if item.kind == ckList and item.items.len == 2 and
@@ -118,22 +117,22 @@ proc macroexpand*(form: CljVal): CljVal =
proc threadingMacro(args: seq[CljVal], reverse: bool): CljVal =
if args.len < 2:
raise newException(CatchableError, "Threading macro requires at least 2 arguments")
var result = args[0]
var acc = args[0]
for i in 1..<args.len:
let step = args[i]
if step.kind == ckList and step.items.len > 0:
var newItems = step.items
if reverse:
newItems.add(result)
newItems.add(acc)
else:
newItems.insert(result, 1)
result = cljList(newItems)
newItems.insert(acc, 1)
acc = cljList(newItems)
elif step.kind == ckSymbol:
# (-> x f) => (f x)
result = cljList(@[step, result])
acc = cljList(@[step, acc])
else:
raise newException(CatchableError, "Threading macro requires list or symbol forms")
result
acc
proc initBuiltinMacros*() =
# ->
@@ -324,17 +323,17 @@ proc initBuiltinMacros*() =
raise newException(CatchableError, "as-> requires at least 3 arguments")
let expr = args[0]
let name = args[1]
var result = expr
var acc = expr
for i in 2..<args.len:
result = cljList(@[cljSymbol("let"), cljVector(@[name, result]), args[i]])
result
acc = cljList(@[cljSymbol("let"), cljVector(@[name, acc]), args[i]])
acc
)
# some->
defineMacro("some->", proc(args: seq[CljVal]): CljVal =
if args.len < 2:
raise newException(CatchableError, "some-> requires at least 2 arguments")
var result = args[0]
var acc = args[0]
for i in 1..<args.len:
let step = args[i]
let gs = cljSymbol(gensymName("st_"))
@@ -347,17 +346,17 @@ proc initBuiltinMacros*() =
threaded = cljList(@[step, gs])
else:
threaded = step
result = cljList(@[cljSymbol("let"), cljVector(@[gs, result]),
acc = cljList(@[cljSymbol("let"), cljVector(@[gs, acc]),
cljList(@[cljSymbol("if"), cljList(@[cljSymbol("nil?"), gs]),
cljNil(), threaded])])
result
acc
)
# some->>
defineMacro("some->>", proc(args: seq[CljVal]): CljVal =
if args.len < 2:
raise newException(CatchableError, "some->> requires at least 2 arguments")
var result = args[0]
var acc = args[0]
for i in 1..<args.len:
let step = args[i]
let gs = cljSymbol(gensymName("stg_"))
@@ -370,10 +369,10 @@ proc initBuiltinMacros*() =
threaded = cljList(@[step, gs])
else:
threaded = step
result = cljList(@[cljSymbol("let"), cljVector(@[gs, result]),
acc = cljList(@[cljSymbol("let"), cljVector(@[gs, acc]),
cljList(@[cljSymbol("if"), cljList(@[cljSymbol("nil?"), gs]),
cljNil(), threaded])])
result
acc
)
# for (simplified — single binding only)
@@ -458,7 +457,6 @@ proc initBuiltinMacros*() =
let body = args[1..^1]
if binding.kind != ckVector or binding.items.len != 2:
raise newException(CatchableError, "with-open requires [name init]")
let sym = binding.items[0]
let init = binding.items[1]
let gs = cljSymbol(gensymName("wo_"))
cljList(@[cljSymbol("let"), cljVector(@[gs, init]),