Textadept: Outlining code using ctags
local ctags = {}
local function make_ctags(path, source)
ui.print("----[generating ctags...]----")
local dir, _ = split(path)
local tags_filepath = dir .. "/tags"
local cmd = string.format('ctags -f %s %s', tags_filepath, source)
ui.print("Executing command:", cmd)
local success, type, code = os.execute(cmd)
if not success then
ui.print("ctags command failed with type:", type, "and code:", code)
else
ui.print("generating ctags success")
end
end
local function parse_ctags(file_path, source, force_gen)
ui.print("------[Parsing]------")
local tags = {}
if force_gen or not lfs.attributes(file_path) then
make_ctags(file_path, source)
end
local tag_file, err = io.open(file_path, "r")
local dir, _ = split(file_path)
if not tag_file then -- Error check
ui.print("Error opening ctags file:", file_path, err)
return tags
end
for line in tag_file:lines() do
if line:sub(1,1) == "!" then
-- Skip lines starting with '!'
goto continue
end
local name, file, pattern = line:match("^(%S+)\t(%S+)\t/(.-)%$/;")
--if not (name and file and pattern) then
-- ui.print("Failed to match:", line)
--end
if name and file and pattern then
table.insert(tags, {name = name, file = file, pattern = pattern})
end
::continue::
end
tag_file:close()
return tags
end
function ctags.select_symbol(force_gen)
local dir, file = split()
local tpath = dir.."/tags"
local tags = parse_ctags(tpath, buffer.filename, force_gen)
local items = {}
for _, tag in ipairs(tags) do
table.insert(items, tag.name)
end
assert(#items>0, "no ctags found.")
local choice = ui.dialogs.list{
title = "Select Symbol",
items = items,
}
if choice then
local tag = tags[choice]
local tfile, err = io.open(tag.file, "r")
if not tfile then
ui.print("error opening file: "..tag.file, err)
end
local lineno = 0
-- Extract and escape the relevant part of the pattern
local epatt = tag.pattern:gsub('([%(%)%.%%%+%-%*%?%[%^%$])', '%%%1')
epatt = epatt:gsub("^%%^", "")
for line in tfile:lines() do
lineno = lineno + 1
if line:match(epatt) then
break
end
end
tfile:close()
-- Open the file and navigate to the symbol's line
io.open_file(tag.file)
buffer:goto_line(lineno-1)
end
end
return ctags
Lua Minimal Vector Lib (2D)
-- Vector Library
local vec = {} -- Create the vector table
-- Define the new function within the vec table
function vec:new(x, y)
x = x or 0
y = y or 0
assert(type(x) == "number" and type(y) == "number", "x and y must be numbers")
local t = {x = x, y = y}
setmetatable(t, self) -- Set the metatable to vec
self.__index = self -- Set the index to the table itself
return t
end
-- Define the type method within the vec table
function vec:type()
return "vector"
end
-- Define the dot product function within the vec table
function vec:dot(v1, v2)
return v1.x * v2.x + v1.y * v2.y
end
-- Define the __div metamethod
function vec.__div(a, b)
assert(type(b) == "number", "divisor should be a number")
return vec:new(a.x / b, a.y / b)
end
-- Define the __mul metamethod
function vec.__mul(a, b)
if type(a) == "number" then
return vec:new(b.x * a, b.y * a)
elseif type(b) == "number" then
return vec:new(a.x * b, a.y * b)
else
return a:dot(b, a)
end
end
-- Define the __unm metamethod
function vec.__unm(v)
return vec:new(-v.x, -v.y)
end
-- Define the __add metamethod
function vec.__add(a, b)
assert(getmetatable(a) == vec and getmetatable(b) == vec, "can't add vec and non-vec")
return vec:new(a.x + b.x, a.y + b.y)
end
function vec.__sub(a, b)
assert(getmetatable(a) == vec and getmetatable(b) == vec, "can't subtract vec and non-vec")
return vec:new(a.x - b.x, a.y - b.y)
end
-- Define the __eq metamethod
function vec.__eq(a, b)
return a.x == b.x and a.y == b.y
end
-- Define the len method within the vec table
function vec:len()
return math.sqrt(self.x * self.x + self.y * self.y)
end
-- Define the norm method within the vec table
function vec:norm()
local length = self:len()
return self / length
end
-- Define the __tostring metamethod
function vec.__tostring(self)
return string.format("<%g, %g>", self.x, self.y)
end
-- Define the angle method within the vec table
function vec:angle(v)
local dot_product = self:dot(self, v)
local mag_product = self:len() * v:len()
local angle_rad = math.acos(dot_product / mag_product)
return angle_rad * (180 / math.pi) -- Convert radians to degrees
end
-- Define the direction method within the vec table
function vec:direction()
local angle_rad = math.atan2(self.y, self.x)
return angle_rad * (180 / math.pi) -- Convert radians to degrees
end
-- Define the cross product method within the vec table
-- return a scalar value of the z coord
function vec:cross(v)
assert(self.z == nil and v.z == nil, "Cross product only defined for 2D vectors")
local cross_z = self.x * v.y - self.y * v.x
return cross_z
end
-- Define the projection method within the vec table
function vec:project_onto(v)
local dot_product = self:dot(self, v)
local mag_square = v:len() ^ 2
local projection_scale = dot_product / mag_square
return v * projection_scale -- Adjusted multiplication
end
-- Define the rejection method within the vec table
function vec:reject_from(v)
local projection = self:project_onto(v)
return vec:new(self.x - projection.x, self.y - projection.y)
end
function vec:orientation(v)
-- Calculate the orientation of three vectors
local determinant = self.x * v.y - self.y * v.x
if determinant > 0 then
return "counterclockwise"
elseif determinant < 0 then
return "clockwise"
else
return "collinear"
end
end
function vec:triangle_area(v)
-- Calculate the area of a triangle formed by two vectors
return 0.5 * math.abs(self:cross(v))
end
function vec:perpendicular()
-- Calculate the perpendicular vector
return vec:new(-self.y, self.x)
end
function vec:polar_to_cartesian(r, theta)
-- Convert polar coordinates to Cartesian coordinates
local x = r * math.cos(theta)
local y = r * math.sin(theta)
return vec:new(x, y)
end
function vec:cartesian_to_polar()
-- Convert Cartesian coordinates to polar coordinates
local r = self:len()
local theta = math.atan2(self.y, self.x)
return r, theta
end
function vec:vector_area(v)
-- Calculate the signed area of a polygon defined by a set of vectors
local cross_product_sum = self:cross(v)
return 0.5 * cross_product_sum
end
function vec:reflect_about_line(normal_vector)
-- Reflect a vector about an arbitrary line defined by its normal vector
local projection = self:project_onto(normal_vector)
local reflection = self - projection * 2
return reflection
end
function vec:scale_by_components(sx, sy)
-- Scale a vector by different factors for its x and y components
return vec:new(self.x * sx, self.y * sy)
end
function vec:displacement_to(v)
-- Calculate the displacement vector between two points defined by vectors
local dx = v.x - self.x
local dy = v.y - self.y
return vec:new(dx, dy)
end
function vec:midpoint(v)
-- Calculate the midpoint of a vector (considering it as a line segment)
local mid_x = (self.x + v.x) / 2
local mid_y = (self.y + v.y) / 2
return vec:new(mid_x, mid_y)
end
-- Testing function
local function VecTest()
local vec1 = vec:new(3, 4)
local vec2 = vec:new(1, 2)
local vec3 = vec:new(-2, 5)
print("Testing Vector Library")
print(string.rep("-", 25))
print("Vector 1:", vec1)
print("Vector 2:", vec2)
print("Vector 1 Type:", vec1:type())
local sum = vec1 + vec2
local scaled = vec1 * 2
local dotProduct = vec1 * vec2
local normalized = vec1:norm()
print("Vector Sum:", sum)
print("Vector Scaled:", scaled)
print("Vector Dot Product:", dotProduct)
print("Vector Normalized:", normalized)
print(string.rep("-", 25))
local angle_deg = vec1:angle(vec2)
local direction_deg = vec1:direction()
print("Angle between vectors:", angle_deg)
print("Direction of vector 1:", direction_deg)
print(string.rep("-", 25))
local cross_product = vec1:cross(vec2)
local projected_vec = vec1:project_onto(vec2)
local rejected_vec = vec1:reject_from(vec2)
print("Cross Product:", cross_product)
print("Projected Vector:", projected_vec)
print("Rejected Vector:", rejected_vec)
print(string.rep("-", 25))
print(string.rep("-", 25))
-- Test angle calculation
local angle = vec1:angle(vec2)
print("Angle between vec1 and vec2:", angle)
-- Test direction calculation
local direction = vec1:direction()
print("Direction of vec1:", direction)
-- Test vector area of polygon
local area = vec1:vector_area(vec2)
print("Vector area of polygon formed by vec1 and vec2:", area)
-- Test vector reflection about line
local normal_vector = vec:new(1, 1):norm()
local reflected_vec = vec3:reflect_about_line(normal_vector)
print("Reflected vector of vec3 about line:", reflected_vec)
-- Test vector scaling by components
local scaled_vec = vec1:scale_by_components(2, 3)
print("Scaled vector of vec1 by components:", scaled_vec)
-- Test vector displacement between points
local displacement = vec1:displacement_to(vec2)
print("Displacement vector between vec1 and vec2:", displacement)
-- Test vector midpoint
local midpoint = vec1:midpoint(vec2)
print("Midpoint between vec1 and vec2:", midpoint)
print(string.rep("-", 25))
end
-- Run the testing function
VecTest()
Lua Minimal Vector Lib (2D)
local vec = { new = function(_,x,y) local t = { x=x or 0, y=y or 0 }; setmetatable(t, _); _.index = _; return t end, Type = function() return "vector" end, D = function(_,a,b) return a.x * b.x + a.y * b.y end, __div = function(_,a,b) assert(type(b) == "number"); return vec.new(_, a.x/b, a.y/b) end, __mul = function(_,a,b) if type(a) == "number" then return vec.new(_, b.x*a, b.y*a) elseif type(b) == "number" then return vec.new(_, a.x*b, a.y*b) else return a:D(b, a) end end, __unm = function(v) return vec.new(_, -v.x, -v.y) end, __add = function(_,a,b) assert(getmetatable(a) == vec and getmetatable(b) == vec); return vec.new(_, a.x+b.x, a.y+b.y) end, __eq = function(a,b) return a.x == b.x and a.y == b.y end, len = function(self) return math.sqrt(self.x*self.x + self.y*self.y) end, norm = function(self) return self / self:len() end, __tostring = function(self) return string.format("<%g, %g>", self.x, self.y) end, angle = function(a,b) local d = a:D(a,b); local m = a:len() * b:len(); local r = math.acos(d/m); return r * (180/math.pi) end, direction = function(a) return math.deg(math.atan2(a.y, a.x)) end, area = function(a,b) return a:D(a,b) * 0.5 end, reflect = function(v,n) return v - (v:project(n) * 2) end, scale = function(v,sx,sy) return vec.new(_, v.x*sx, v.y*sy) end, displacement = function(a,b) return vec.new(_, b.x-a.x, b.y-a.y) end, midpoint = function(a,b) return vec.new(_, 0.5*(a.x+b.x), 0.5*(a.y+b.y)) end, __sub = function(a,b) assert(getmetatable(a) == vec and getmetatable(b) == vec); return vec.new(_, a.x-b.x, a.y-b.y) end }
Vector2D in Lua minimized
Vector2D = {new = function(x, y) return setmetatable({x = x, y = y}, {__index = Vector2D}) end, __add = function(v1, v2) return Vector2D:new(v1.x + v2.x, v1.y + v2.y) end, __sub = function(v1, v2) return Vector2D:new(v1.x - v2.x, v1.y - v2.y) end, __mul = function(v, scalar) return Vector2D:new(v.x * scalar, v.y * scalar) end, length = function(v) return math.sqrt(v.x * v.x + v.y * v.y) end, normalize = function(v) local len = v:length() return len > 0 and v * (1 / len) or Vector2D:new(0, 0) end, angle = function(v) return math.atan2(v.y, v.x) end}
Perlin Lua
local function mix(a, b, t) return (t * (b - a)) + a end
local function mod(a, b) return ((a % b) + b) % b end
local function fract(x) return x - math.floor(x) end
local function clamp(a, b, c) return math.min(math.max(a, b), c) end
local function dot(a, b)
local s = 0
for i = 1, #a do
s = s + a[i] * b[i]
end
return s
end
local function sign(x) return x > 0 and 1 or (x < 0 and -1 or 0) end
local function pow2(a, b) return math.pow(math.abs(a), b) * sign(a) end
local function pal(i, r, g, b)
i = i < 0 and 0 or (i > 15 and 15 or i)
if r == nil and g == nil and b == nil then
return peek(0x3fc0 + (i * 3)),
peek(0x3fc0 + (i * 3) + 1),
peek(0x3fc0 + (i * 3) + 2)
else
poke(0x3fc0 + (i * 3) + 2, clamp(b, 0, 255))
poke(0x3fc0 + (i * 3) + 1, clamp(g, 0, 255))
poke(0x3fc0 + (i * 3), clamp(r, 0, 255))
end
end
local seed = {
a = 500 + (math.random() * 1e4),
fx = 500 + (math.random() * 1e4),
fy = 500 + (math.random() * 1e4),
px = math.random() - 0.5,
py = math.random() - 0.5
}
local function pseudorandom2D(x, y)
return fract(math.sin(dot({x + seed.px, y + seed.py}, {seed.fx, seed.fy})) * seed.a)
end
local function perlin(x, y)
return mix(
mix(
pseudorandom2D(math.floor(x), math.floor(y)),
pseudorandom2D(math.floor(x) + 1, math.floor(y)),
fract(x)
),
mix(
pseudorandom2D(math.floor(x), math.floor(y) + 1),
pseudorandom2D(math.floor(x) + 1, math.floor(y) + 1),
fract(x)
),
fract(y)
)
end
local function f(x, y)
x = x / 15
y = y / 15
local iterations = 4
local sum = 0
for i = 0, iterations - 1 do
seed.a = 500 + (fract(math.sin((i + 0.512) * 512) * 725.63) * 1e4)
sum = sum + perlin(x * (i + 1), y * (i + 1))
end
return sum / iterations
end