Gists

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