Compare commits

...

3 Commits

7 changed files with 1182 additions and 0 deletions

203
helper.lua Normal file
View File

@@ -0,0 +1,203 @@
local old_print = print
function print(...)
local info = debug.getinfo(2)
local line = info.currentline
local name = info.source
old_print(string.format("%i%s> ",line,name),...)
end
function log(...)
old_print(...)
end
function map(tab,func)
local new = {}
for index,item in pairs(tab) do
new[index] = func(item)
end
return new
end
-- HELPER FUNCTIONS
-- Insert every item in t1 into t0
function just(...)
local items = {...}
return function()
return table.unpack(items)
end
end
id = function(...) return ... end
function union(t0,t1)
for index,item in pairs(t0) do
t0[index] = t1
end
return t0
end
-- Iterate (ipairs without the index)
function iterate(...)
local iterator,tab,i = pairs(...)
return function(...)
local index,item = iterator(tab,i)
i = index
return item
end,tab,i
end
function indices(t)
if type(t) ~= "table" then
error(
string.format(
"Argument 1 '%s' must be a table",
tostring(t)
)
,2)
end
local indices = {}
for index,_ in pairs(t) do
table.insert(indices,index)
end
return indices
end
-- Ensures a table has a metatable
function ensure_metatable(t)
local meta = getmetatable(t)
if not meta then meta = {} setmetatable(t,meta) end
return meta
end
function strings(t,item)
ensure_metatable(t).__tostring = item
end
-- Makes a table callable
function calls(t,fun)
ensure_metatable(t).__call = fun
end
-- Makes a table record access
function indexes(t,fun)
ensure_metatable(t).__index = fun
end
-- Makes a table record setting
function modifies(t,fun)
ensure_metatable(t).__newindex = fun
end
-- Shallow table to string
function table_tostring(tab,sep)
local items = {}
for item in iterate(tab) do
table.insert(items,tostring(item))
end
return table.concat(items,sep)
end
function type_of(item)
local type_name = type(item)
if type_name == "table" then
local meta = getmetatable(item)
if not meta then
return "table"
else
return meta
end
else
return type_name
end
end
-- DEBUGGING FUNCTIONS
-- Runs a function
function assert_meta(...)
local metas = {...}
return function(x,raise,handler)
handler = handler or error
local meta = getmetatable(x)
for tab in iterate(metas) do
if meta == tab then return end
end
local s_metas = {}
for meta in iterate(metas) do
table.insert(s_metas,tostring(meta))
end
local level = 2
local msg = string.format(
"Expected metatables '%s' but got '%s'",
table.concat(s_metas,","),
type(x)
)
if raise then
level = 3
msg = string.format(raise,msg)
end
handler(msg,level)
end
end
function assert_type(...)
local types = {...}
return function(x,raise)
local t = type(x)
for name in iterate(types) do
if t == name then return end
end
local level = 2
local msg = string.format(
"Expected type '%s' but got '%s'",
table_tostring(types," or "),
type(x))
-- For argument errors
if raise then
level = 3
msg = string.format(raise,msg)
end
error(msg,level)
end
end
-- HELPER FUNCTIONS
function case_of(t)
return function(item,...)
return (t[item] or error(
string.format(
"Couldn't match '%s' in case.",
tostring(item)
),2
))(...)
end
end
-- Creates a (p)OOP class
function class(name)
local meta = {}
union(meta,{restrict = {}})
meta.__index = meta
strings(meta,just(name))
calls(meta,function(meta,...)
local new = {}
setmetatable(new,meta)
if meta.new then new:new(...) end
return new
end)
meta.__tostring = function(this)
if meta.string then return this:string() end
return name
end
return meta
end
-- Read a file's full contents
function read(path)
local file = io.open(path)
if not file then
error(
string.match("Could not open file '%s'.",path),3
)
end
local content = file:read("a")
return content
end
return _G

160
interpret.lua Normal file
View File

@@ -0,0 +1,160 @@
require("parse")
-- TODO: This should really be a separate API and module
-- please break it out
-- Interpret some text
function interpret(content,uri,chain)
-- LOCALS
-- The pattern for words inbetween expressions
local expressionWordPattern = "(.*)"
-- The patterns to open and close expressions,
-- the words scattered inbetween them will be matches
local expressionOpenPattern = "%("
local expressionClosePattern = "%)"
local subExpressionOpenPattern = "%:"
local subExpressionClosePattern = "%,"
local blockOpenPattern = "%{"
local blockClosePattern = "%}"
local blockDelimiterPattern = "[;]+"
-- So that all functions have access to eachother
local consume,
consumeExpression,
processWords,
processClosure,
processOpening,
consumeBlock,
consumeText,
consumeNumber
local consumer = Consumer(content)
local function expression(...)
return Expression(...):locate(
string.format(
"%i:%i",
consumer.row,
consumer.col
),uri)
end
local baseExpression = expression()
-- FUNCTIONS
-- Consume an expression, with its sub expressions
-- given that an opening has just been consumed
local singleLineStringPattern = "\""
local function singleLineStringMeal(current,match)
return function(words,_)
current:insert(words,consumer:consume({
[match] = function(words,_)
return expression({"text",Expression({words})})
end
}))
end
end
local multiLineStringOpenPattern = "%[%["
local multiLineStringClosePattern = "%]%]"
local function multiLineStringMeal(current,match)
return function(words,_)
current:insert(words,consumer:consume({
["[\n\r]"] = function()
error("Incomplete string literal")
end,
[match] = function(words,_)
return expression({"text",Expression({words})})
end
}))
end
end
local uriOpenPattern = "<"
local uriClosePattern = ">"
local function URIMeal(current,match)
return function(words,_)
current:insert(words,consumer:consume({
["[\n\r]"] = function()
current:error("Incomplete URI literal")
end,
[match] = function(path)
return read(path)
end
}))
end
end
local function expressionMeal(current)
return function(words,_)
current:insert(words,consumeExpression())
end
end
function consumeBlock()
local expressions = {}
local current = expression()
local loop = true
while loop do
local expr = consumer:consume({
[uriOpenPattern] = URIMeal(current,uriClosePattern),
[expressionOpenPattern] = expressionMeal(current),
[multiLineStringOpenPattern] =
multiLineStringMeal(
current,multiLineStringClosePattern),
[singleLineStringPattern] =
singleLineStringMeal(
current,singleLineStringPattern),
[blockDelimiterPattern] = function(words,_)
if current:empty() then
error("Extravenous semicolon.")
end
table.insert(expressions,current)
current = expression()
end,
[blockClosePattern] = function(words,_)
current:insert(words)
loop = false
end
})
end
if #current.items ~= 0 then
table.insert(expressions,current)
end
return expression(expressions)
end
function consumeExpression()
local current = expression()
-- Loop, adding new expressions and words,
-- until closing that is
local loop = true
while loop do
local remaining = consumer:remaining()
local expr = consumer:consume({
[uriOpenPattern] = URIMeal(current,uriClosePattern),
[expressionOpenPattern] = expressionMeal(current),
[multiLineStringOpenPattern] =
multiLineStringMeal(
current,multiLineStringClosePattern),
[singleLineStringPattern] =
singleLineStringMeal(
current,singleLineStringPattern),
[expressionOpenPattern] = expressionMeal(current),
[expressionClosePattern] = function(words,_)
current:insert(words)
loop = false
end,
[blockOpenPattern] = function(words,_)
current:insert(
words,
consumeBlock()
)
end,
["$"] = function(words,last)
current:insert(remaining)
loop = false
end
})
-- This single line below made me procrastinate life for a total of 4 hours on instagram reels; lock in.
-- if not expr then print("brk") break end -- Since now closing
end
return current
end
return consumeExpression()
-- TODO: check for later expressions please?
end
return _G

225
main.lua Normal file
View File

@@ -0,0 +1,225 @@
require("interpret")
local nelli_scope = Scope()
local function B(abstract,callback)
nelli_scope:insert(
Binding(
interpret(abstract),
callback
)
)
end
local function R(scope,expression,chain,name)
name = name or "?"
assert_meta(Chain)(chain,"Arg 'chain' #1: %s")
local chain = Chain(expression:link(name)):from(chain)
return scope:run(expression,chain)
end
B("print (text)",function(s,e,c)
log(R(s,e.text,c,"print: text"))
end)
B("text (literal)",function(s,e,c)
return e.literal:text()
end)
B("do (expressions)",function(s,e,c)
--assert_meta(Chain)(chain,"Arg 'chain' #3: %s")
scope = Scope()
scope.parent = s
local res
for item in iterate(e.expressions.items) do
if type_of(item) ~= Expression then
error(
string.format(
"Unexpected words '%s' in 'do' expression.",
tostring(item)
)
)
end
res = R(s,item,c,"do: line")
end
return res
end)
B("error (text)",function(s,e,c)
error("nel: "..R(s,e.text,c,"error: message"))
end)
B("if (predicate) then (expression)",function(s,e,c)
if R(s,e.predicate,c,"if: predicate") then
return R(s,e.expression,c,"if: result")
end
end)
B("true",function(s,e,c) return true end)
B("false",function(s,e,c) return false end)
B("(constant) = (expression)",function(s,e,c)
local value = R(s,e.expression,c,"constant: expression")
s:insert(
Binding(e.constant:text(),function(s,e,c)
return value
end)
)
end)
B("format (string) with (terms)",function(s,e,c)
local items = {}
for expression in iterate(e.terms.items) do
table.insert(items,R(s,expression),c,"format: term")
end
return string.format(
R(s,e.string,c,"format: string"),
table.unpack(items)
)
end)
B("while (predicate) (expression)",function(s,e,c)
while R(s,e.predicate,c,"while: predicate") do
R(s,e.expression,c,"while: loop")
end
end)
B("repeat (expression) while (predicate)",function(s,e,c)
while true do
R(s,e.expression,c,"repeat: expression")
if not R(s,e.predicate,c,"repeat: predicate") then
break
end
end
end)
B("repeat (expression) until (predicate)",function(s,e,c)
while true do
R(s,e.expression,c,"repeat: expression")
if R(s,e.predicate,c,"repeat: predicate") then
break
end
end
end)
B("new table",function(s,e,c)
return {}
end)
B("(index) of (table)",function(s,e,c)
return (R(s,e.table,"of: index"))[R(s,e.index,c,"of: table")]
end)
B("set (index) of (table) to (item)",function(s,e,c)
R(s,e.table,c,"of-to: index")[R(s,e.index,c,"of-to: table")] = s:run(e.item,c,"of-to: item")
end)
B("remove (index) of (table)",function(s,e,c)
(R(s,e.table,"remove: table"))[R(s,e.index,c,"remove: index")] = nil
end)
B("nil",function(s,e,c)
return nil
end)
--[[ Note
A macro executes in the same scope of the callee.
A defintion executes in the scope it was defined.
I would argue that macros are more unpredictable!
However, they allow for some very clean code.
--]]
B("macro (macro) expands to (expression)",function(s,e,c)
s:insert(Binding(e.abstract,function(_s,_e,_c)
local scope = Scope()
scope.parent = _s
for identifier,expression in pairs(_e) do
scope:insert(Binding(Expression({identifier}),R(_s,expression,_c)))
end
return R(scope,e.expression,_c,"macro: expression")
end))
end)
B("define (abstract) as (expression)",function(s,e,c)
s:insert(Binding(e.abstract,function(_s,_e,_c)
local scope = Scope()
scope.parent = s
for identifier,expression in pairs(_e) do
scope:insert(Binding(Expression({identifier}),R(_s,expression,_c)))
end
return R(scope,e.expression,_c,"define: expression")
end))
end)
local List = class("List")
function List:new(...)
self.items = {...}
end
B("new list",function(s,e,c)
return List()
end)
B("insert (item) into (list)",function(s,e,c)
table.insert(R(s,e.list).items,R(s,e.item),c,c)
end)
B("insert (item) into (list) at (index)",function(s,e,c)
table.insert(s:evaulate(e.list).items,R(s,e.index),R(s,item),c,c)
end)
B("remove (needle) from (haystack)",function(s,e,c)
local tab = R(s,e.haystack,c)
table.remove(tab,table.find(tab,R(s,e.needle)),c)
end)
B("remove from (haystack) at (index)",function(s,e,c)
table.remove(R(s,e.list),R(s,e.index),c,c)
end)
local Variable = class("Variable")
function Variable:new()
end
function Variable:set(item)
self.data = item
end
function Variable:get()
return self.data
end
B("let (variable)",function(s,e,c)
local variable = Variable()
s:insert(
Binding(e.variable,function(s,e,c)
return variable
end)
)
return variable
end)
B("set (variable) to (expression)",function(s,e,c)
local var = R(s,e.variable,c,"set: identifier")
local value = R(s,e.expression,c,"set: expression")
assert_meta(Variable)(var)
var:set(value)
end)
B("get (variable)",function(s,e,c)
local var = R(s,e.variable,c)
return var:get(value)
end)
local args = {...}
local function main()
-- Take arguments as neli files to read and interpret
local last
local root = Chain(
string.format(
"in cmd 'nel {%s}'",
table.concat(args,";")
)
)
local success,result = xpcall(function()
for _,parameter in pairs(args) do
last = parameter
local chain = Chain(
string.format("in 'call: root' @'%s'",parameter)
):from(root)
local root = interpret(
read(parameter),
parameter,
chain
)
assert_meta(Chain)(chain,"?")
nelli_scope:run(root,chain)
end
end,function(msg)
-- If this is a 'nel:' error, strip the line responsible
-- Otherwise just return the whole traceback since something went really bad
local match = msg:match("nel:%s(.*)")
if match then
return match
else
return "internal: "..debug.traceback(msg,2)
end
end)
if not success then
log(string.format(
"nel: %s\nNEL traceback:\n\t%s",
result,
table.concat(root:flatten(),"\n\t")
))
end
end
main()

13
note Normal file
View File

@@ -0,0 +1,13 @@
I am thinking for the syntax in nel.
How can we have multiple arguments for something?
It feels rather stupid allowing this really.
It's not very clear, a list is a list in any case.
So maybe we really should just have another
substatement, and forget about powering up
the abstracts, for now? ...?
Well then... in that case.
We only need to make sure scoping works.
Which means, scopes inherit from eachother,
and applying congruent bindings causes an error.
I think.

371
parse.lua Normal file
View File

@@ -0,0 +1,371 @@
require("helper")
-- CLASS DEFINITIONS
-- A stream of text (kind of)
-- with some helping methods
Reader = class("Reader")
-- Construct a reader from
function Reader:new(text)
assert_type("string")(text,"Arg 'text' #1: %s")
self.text = text
end
-- Get the substring of the readers text in a bounds
function Reader:get(first,final)
assert_type("number")(first,"Arg 'first' #1: %s")
assert_type("number","nil")(final,"Arg 'final' #2: %s")
return self.text:sub(first,final)
end
-- Match on the reader's text from an index
function Reader:find(pattern,init)
assert_type("string")(pattern,"Arg 'pattern' #1: %s")
assert_type("number","nil")(init,"Arg 'init' #2: %s")
return self.text:find(pattern,init)
end
function Reader:match(pattern,init)
assert_type("string")(pattern,"Arg 'pattern' #1: %s")
assert_type("number")(init,"Arg 'init' #2: %s")
return self.text:match(pattern,init)
end
-- A range of text being considered
-- like a cursor
Range = class("Range")
-- Construct a range of text from a reader and bounds
function Range:new(reader,first,final)
assert_meta(Reader)(reader)
assert_type("number","nil")(first,"Arg 'first' #1: %s")
assert_type("number","nil")(final,"Arg 'final' #2: %s")
self.reader = reader
self.first = first
self.final = final
end
function Range:text()
return self.reader:get(self.first or 1,self.final)
end
function Range:find(pattern)
return self.reader:find(pattern,self.first)
end
function Range:move(first,final)
assert_type("number","nil")(first,"Arg 'first' #1: %s")
assert_type("number","nil")(final,"Arg 'final' #2: %s")
self.first = first
self.final = final
-- note that this function returns itself
return self
end
Expression = class("Expression")
-- Construct an expression from items (or not)
function Expression:new(items)
items = items or {}
assert_type("table")(items)
self.items = {}
for item in iterate(items) do
self:insert(item)
end
end
function Expression:empty()
return #self.items == 0
end
-- insert a word or sub expression into this one
function Expression:insert(...)
-- closures for nvim highlighting
local function insert_word(word)
-- Whitespace might confuse bindings, remove them
local cleaned = word:match("^%s*(.-)%s*$")
if cleaned ~= "" then
table.insert(self.items,cleaned)
end
end
local function insert_expression(expr)
assert_meta(expr,Expression)
table.insert(self.items,expr)
end
for item in iterate({...}) do
case_of({
table = function(expr)
insert_expression(expr)
end,
string = function(word)
insert_word(word)
end
})(type(item),item)
end
end
function Expression:string()
local parts = {}
for index,item in pairs(self.items) do
parts[index] = tostring(item)
end
return string.format("(%s)",table.concat(parts," "))
end
function Expression:abstract(infer)
local parts = {}
local count = 0
for index,item in pairs(self.items) do
parts[index] = case_of({
[Expression] = function(item)
local text
if infer then
text = item:text()
if not text then
count = count + 1
text = tostring(count)
end
else
text = "..."
end
return Expression({text})
end,
string = id
})(type_of(item),item)
end
return Expression(parts)
end
function Expression:text()
-- Get the text
local text = self.items[#self.items]
-- Ensure that the subexpression is valid abstract
if type(text) ~= "string" then return end
return text
end
function Expression:locate(str,uri)
self.location = str
self.source = uri
return self
end
function Expression:link(msg)
return string.format(
"in '%s' @%s (%s)",
msg,
tostring(self),
tostring(self.location or "?"),
tostring(self.source or "?.nel")
)
end
Consumer = class("Consumer")
function Consumer:new(content)
self.range = Range(Reader(content))
self.col = 1
self.row = 1
end
function Consumer:remaining()
return self.range:text()
end
function Consumer:mark()
end
-- From a table of actions of patterns,
-- consume the earliest pattern (index)
-- and call the value
function Consumer:consume(t)
-- t: {string = function...}
assert_type("table")(t,"Arg 't' #1: %s")
if not next(t) then
error("The match table cannot be empty!",2)
end
for index,func in pairs(t) do
assert_type("string")(index,"Bad 't' index: %s")
assert_type("function")(func,"Bad 't' item: %s")
end
local origin = self.range.first or 1
-- Get the next earliest match
local findex,ffinal,fpattern,ffunc,fexcess
for pattern,new_func in pairs(t) do
local new_index,new_final = self.range:find(pattern)
if new_index and
((not findex) or (findex > new_index))
then
if not new_index then return end
findex = new_index
ffinal = new_final
fpattern = pattern
ffunc = new_func
fexcess = self.range.reader:get(
self.range.first or 1,
new_final - 1
)
end
end
-- Pass into the func
if not ffunc then
return nil
end
assert(findex) assert(ffinal)
self.range:move(ffinal+1) -- Move range to after the match
local fmatch = self.range.reader:match(fpattern,findex)
-- Pass back consumed result to
local sum = self.range.reader:get(origin+1,self.range.first)
:gsub("\r\n","\n")
:gsub("\r","\n")
for char in sum:gmatch(".") do
if char == "\n" then
self.row = self.row + 1
self.col = 1
else
self.col = self.col + 1
end
end
return ffunc(fexcess,fmatch)
end
Binding = class("Binding")
-- Construct from a neli string to infer a binding
-- note that you must wrap this definition in "(<def>)"!
function Binding:new(expression,callback)
assert_meta(Expression)(expression,"Arg 'expression' #1: %s")
if type_of(callback) == "function" then
self.callback = callback
else
self.value = callback
end
self.template = expression:abstract(true)
end
function Binding:string()
return string.format("Binding %s: %s",self.template,tostring(self.value or self.callback))
end
function Binding:call(s,e,c)
assert_meta(Scope)(s)
assert_meta(Chain)(c)
return self.value or self.callback(s,e,c)
end
function Binding:check(expression)
assert_meta(Expression)(expression,"Arg 'expression' #1: %s")
local candid = expression:abstract()
local data = {}
local index
local loop = true
if #candid.items ~= #self.template.items then
return false
end
while loop do
local old = index
index,template_item = next(self.template.items,old)
index,candid_item = next(candid.items,old)
local result = case_of({
[Expression] = function()
-- item is not an expression, cannot bind
if type_of(candid_item) ~= Expression then
loop = false
else
data[template_item:text()] = expression.items[index]
end
end,
string = function()
-- words don't match, cannot bind
if candid_item ~= template_item then
loop = false
end
end,
["nil"] = function()
-- base case where both expressions terminate together
if not candid_item then
return data
end
end
})(type_of(template_item))
if result then return result end
end
end
Chain = class("Chain")
function Chain:new(data)
assert_type("string")(data,"Arg 'data' #1: %s")
self.data = data
end
function Chain:from(previous)
assert_meta(Chain)(previous,"Arg 'previous' #1: %s")
previous.next = self
self.previous = previous
return self
end
function Chain:string()
return string.format("Chain:%s",table.concat(self:flatten(),", "))
end
function Chain:flatten(tab)
tab = tab or {}
if self.next then
self.next:flatten(tab)
end
table.insert(tab,self.data)
return tab
end
-- The scope of a neli expression under evaluation
-- without exact faith to traditional language scopes
Scope = class("Scope")
function Scope:new(bindings)
self.bindings = {}
for binding in iterate(bindings or {}) do
self:insert(binding)
end
end
function Scope:string()
return string.format("Scope: {\n\t%s\n}",table.concat(map(self.bindings,tostring),"\n\t"))
end
function Scope:insert(binding)
assert_meta(Binding)(binding,"Arg 'binding' #1: %s")
for competitor in iterate(self.bindings) do
if competitor:check(binding.template) then
nerror("Conflicting sibling bindings in scope.")
end
end
table.insert(self.bindings,binding)
end
function Scope:run(expression,chain,original)
original = original or self
assert_meta(Expression)(expression,"Arg 'expression' #1: %s")
assert_meta(Chain)(chain,"Arg 'chain' #2: %s")
-- Could be multiple bindings so make a table
local binds = {}
for binding in iterate(self.bindings) do
local bind = binding:check(expression)
-- Insert into table
if bind then binds[binding] = bind end
end
local binding,bind = next(binds)
-- Check for multiple
if not bind then
if self.parent then
return self.parent:run(expression,chain,self)
else
local extra = ""
if #expression.items == 1 then
local item = expression.items[1]
if type_of(item) == Expression then
extra = extra .. "\nNote: This expression is formed (just bracketed) of another single expression. Maybe too many brackets were used here?"
else
extra = extra .. "\n\tNote: This is a 'text' expression, it has no subexpressions. It is most likely that an expected object definition was not bound to the scope or there is a typo."
end
end
error(
string.format(
"nel: No binding for '%s' in scope.",
tostring(expression:abstract()),
extra
),3
)
end
-- Should never happen!
elseif next(binds,binding) then
local candidates = {}
for binding,bind in pairs(binds) do
table.insert(candidates,tostring(binding.template))
end
error(
string.format(
"nel: Ambiguous bindings in scope for '%s': %s",
tostring(expression:abstract()),
table.concat(candidates)
)
,2)
else
return binding:call(
original,
bind,
chain
)
end
end
return _G

205
session.vim Normal file
View File

@@ -0,0 +1,205 @@
let SessionLoad = 1
let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1
let v:this_session=expand("<sfile>:p")
silent only
silent tabonly
cd ~/Programming/nel/1
if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == ''
let s:wipebuf = bufnr('%')
endif
let s:shortmess_save = &shortmess
if &shortmess =~ 'A'
set shortmess=aoOA
else
set shortmess=aoO
endif
badd +167 main.lua
badd +27 parse.lua
badd +0 term://~/Programming/nel/1//1946:/usr/bin/zsh
badd +0 interpret.lua
badd +0 test.nel
badd +191 helper.lua
argglobal
%argdel
$argadd ~/Programming/nel/1
edit parse.lua
let s:save_splitbelow = &splitbelow
let s:save_splitright = &splitright
set splitbelow splitright
wincmd _ | wincmd |
vsplit
1wincmd h
wincmd _ | wincmd |
split
1wincmd k
wincmd _ | wincmd |
vsplit
1wincmd h
wincmd w
wincmd w
wincmd w
wincmd _ | wincmd |
split
1wincmd k
wincmd w
let &splitbelow = s:save_splitbelow
let &splitright = s:save_splitright
wincmd t
let s:save_winminheight = &winminheight
let s:save_winminwidth = &winminwidth
set winminheight=0
set winheight=1
set winminwidth=0
set winwidth=1
exe '1resize ' . ((&lines * 24 + 19) / 39)
exe 'vert 1resize ' . ((&columns * 60 + 90) / 181)
exe '2resize ' . ((&lines * 24 + 19) / 39)
exe 'vert 2resize ' . ((&columns * 60 + 90) / 181)
exe '3resize ' . ((&lines * 12 + 19) / 39)
exe 'vert 3resize ' . ((&columns * 121 + 90) / 181)
exe '4resize ' . ((&lines * 24 + 19) / 39)
exe 'vert 4resize ' . ((&columns * 59 + 90) / 181)
exe '5resize ' . ((&lines * 12 + 19) / 39)
exe 'vert 5resize ' . ((&columns * 59 + 90) / 181)
argglobal
setlocal foldmethod=manual
setlocal foldexpr=v:lua.vim.treesitter.foldexpr()
setlocal foldmarker={{{,}}}
setlocal foldignore=#
setlocal foldlevel=0
setlocal foldminlines=1
setlocal foldnestmax=20
setlocal foldenable
silent! normal! zE
let &fdl = &fdl
let s:l = 267 - ((8 * winheight(0) + 12) / 24)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 267
normal! 019|
lcd ~/Programming/nel/1
wincmd w
argglobal
if bufexists(fnamemodify("~/Programming/nel/1/interpret.lua", ":p")) | buffer ~/Programming/nel/1/interpret.lua | else | edit ~/Programming/nel/1/interpret.lua | endif
if &buftype ==# 'terminal'
silent file ~/Programming/nel/1/interpret.lua
endif
balt ~/Programming/nel/1/parse.lua
setlocal foldmethod=manual
setlocal foldexpr=v:lua.vim.treesitter.foldexpr()
setlocal foldmarker={{{,}}}
setlocal foldignore=#
setlocal foldlevel=0
setlocal foldminlines=1
setlocal foldnestmax=20
setlocal foldenable
silent! normal! zE
let &fdl = &fdl
let s:l = 58 - ((15 * winheight(0) + 12) / 24)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 58
normal! 034|
lcd ~/Programming/nel/1
wincmd w
argglobal
if bufexists(fnamemodify("term://~/Programming/nel/1//1946:/usr/bin/zsh", ":p")) | buffer term://~/Programming/nel/1//1946:/usr/bin/zsh | else | edit term://~/Programming/nel/1//1946:/usr/bin/zsh | endif
if &buftype ==# 'terminal'
silent file term://~/Programming/nel/1//1946:/usr/bin/zsh
endif
balt ~/Programming/nel/1/parse.lua
setlocal foldmethod=manual
setlocal foldexpr=0
setlocal foldmarker={{{,}}}
setlocal foldignore=#
setlocal foldlevel=0
setlocal foldminlines=1
setlocal foldnestmax=20
setlocal foldenable
let s:l = 947 - ((11 * winheight(0) + 6) / 12)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 947
normal! 040|
lcd ~/Programming/nel/1
wincmd w
argglobal
if bufexists(fnamemodify("~/Programming/nel/1/main.lua", ":p")) | buffer ~/Programming/nel/1/main.lua | else | edit ~/Programming/nel/1/main.lua | endif
if &buftype ==# 'terminal'
silent file ~/Programming/nel/1/main.lua
endif
balt ~/Programming/nel/1/helper.lua
setlocal foldmethod=manual
setlocal foldexpr=v:lua.vim.treesitter.foldexpr()
setlocal foldmarker={{{,}}}
setlocal foldignore=#
setlocal foldlevel=0
setlocal foldminlines=1
setlocal foldnestmax=20
setlocal foldenable
silent! normal! zE
let &fdl = &fdl
let s:l = 178 - ((21 * winheight(0) + 12) / 24)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 178
normal! 012|
lcd ~/Programming/nel/1
wincmd w
argglobal
if bufexists(fnamemodify("~/Programming/nel/1/test.nel", ":p")) | buffer ~/Programming/nel/1/test.nel | else | edit ~/Programming/nel/1/test.nel | endif
if &buftype ==# 'terminal'
silent file ~/Programming/nel/1/test.nel
endif
balt ~/Programming/nel/1/main.lua
setlocal foldmethod=manual
setlocal foldexpr=0
setlocal foldmarker={{{,}}}
setlocal foldignore=#
setlocal foldlevel=0
setlocal foldminlines=1
setlocal foldnestmax=20
setlocal foldenable
silent! normal! zE
let &fdl = &fdl
let s:l = 5 - ((4 * winheight(0) + 6) / 12)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 5
normal! 0
lcd ~/Programming/nel/1
wincmd w
3wincmd w
exe '1resize ' . ((&lines * 24 + 19) / 39)
exe 'vert 1resize ' . ((&columns * 60 + 90) / 181)
exe '2resize ' . ((&lines * 24 + 19) / 39)
exe 'vert 2resize ' . ((&columns * 60 + 90) / 181)
exe '3resize ' . ((&lines * 12 + 19) / 39)
exe 'vert 3resize ' . ((&columns * 121 + 90) / 181)
exe '4resize ' . ((&lines * 24 + 19) / 39)
exe 'vert 4resize ' . ((&columns * 59 + 90) / 181)
exe '5resize ' . ((&lines * 12 + 19) / 39)
exe 'vert 5resize ' . ((&columns * 59 + 90) / 181)
tabnext 1
if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'
silent exe 'bwipe ' . s:wipebuf
endif
unlet! s:wipebuf
set winheight=1 winwidth=20
let &shortmess = s:shortmess_save
let &winminheight = s:save_winminheight
let &winminwidth = s:save_winminwidth
let s:sx = expand("<sfile>:p:r")."x.vim"
if filereadable(s:sx)
exe "source " . fnameescape(s:sx)
endif
let &g:so = s:so_save | let &g:siso = s:siso_save
set hlsearch
doautoall SessionLoadPost
unlet SessionLoad
" vim: set ft=vim :

5
test.nel Normal file
View File

@@ -0,0 +1,5 @@
do {
print "large balls";
define (say (text)) as (print (text));
say "shit";
}