{"id":23305730,"url":"https://github.com/mmsaki/lua-tuorial","last_synced_at":"2025-06-26T07:02:49.418Z","repository":{"id":267318442,"uuid":"900742288","full_name":"mmsaki/lua-tuorial","owner":"mmsaki","description":"🗂️ learning lua","archived":false,"fork":false,"pushed_at":"2024-12-09T18:04:07.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-06T23:46:45.630Z","etag":null,"topics":["lua"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mmsaki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-09T11:45:26.000Z","updated_at":"2024-12-10T06:54:02.000Z","dependencies_parsed_at":"2024-12-09T17:39:48.581Z","dependency_job_id":"8d657563-54ab-43d6-a160-89cd74f34ca3","html_url":"https://github.com/mmsaki/lua-tuorial","commit_stats":null,"previous_names":["mmsaki/lua-tuorial"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mmsaki/lua-tuorial","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Flua-tuorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Flua-tuorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Flua-tuorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Flua-tuorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mmsaki","download_url":"https://codeload.github.com/mmsaki/lua-tuorial/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmsaki%2Flua-tuorial/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262018677,"owners_count":23245618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lua"],"created_at":"2024-12-20T12:14:07.955Z","updated_at":"2025-06-26T07:02:49.403Z","avatar_url":"https://github.com/mmsaki.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lua Tutorial\n\nLearning Lua following tutorials by [Teej](https://x.com/teej_dv/status/1863919864953418087/video/1)\n\n## Comments\n```lua\n-- This is a comment. It starts with two dashes\n--[[ This is also\n    a comment.\n\n    But it spans multiple lines!\n--]]\n```\n\n## Variables: Simple Literals\n```lua\nlocal number = 5\n\nlocal string = \"hello, world\"\nlocal single = 'this works'\nlocal crazy = [[ This\n    is multi line and literal ]]\n\nlocal truth, lies = true, false\n\nlocal nothing = nil\n```\n\n## Variables: Functions\n\n- Example 1\n\n```lua\nlocal greet = function(name)\n    print(\"Hello!\", name)\nend\n\nlocal greet = function(name)\n    -- .. is string concatenation\n    print(\"Greetings, \" .. name .. \"!\")\nend\n```\n\n- Example 2\n\n```lua\nlocal higher_order = function(value)\n    return function(another)\n        return value + another\n    end\nend\n\nlocal add_one = higher_order(1)\nprint(\"add_one(2) -\u003e\", add_one(2))\n\n-- Output\n-- add_one(2) -\u003e 3\n```\n\n## Variables: Tables\n\nTables are like a list ...\n\n```lua\nlocal list = { \"first\", 2, false, function() print(\"Fourth!\") end }\nprint(\"Yup, 1-indexed:\", list[1])\nprint(\"Fourth is 4 ..:\", list[4]())\n-- Output\n-- Yuo, 1-indexed: first\n-- Fourth!\n-- Fourth is 4 ..:\n```\n\nTables being used as a map ...\n\n```lua\nlocal t = {\n    literal_key = \"a string\",\n    [\"an expression\"] = \"also works\",\n    [function() end] = true\n}\n\nprint(\"literal_key    : \", t.literal_key)\nprint(\"an expression  : \", t[\"an expression\"])\nprint(\"function() end : \", t[function() end])\n\n-- Output\n-- literal_key   : a string\n-- an expression : also works\n-- function() end: nil\n```\n\n## Control Flow: `for`\n\n```lua\nlocal favorite_accounts = { \"msakiart\", \"teej_dv\", \"ThePrimeagen\" }\nfor index = 1, #favorite_accounts do\n    print(index, favorite_accounts[index])\nend\n\nfor index, value in ipairs(favorite_accounts) do\n    print(index, value)\nend\n-- Output\n-- 1 msakiart\n-- 2 teej_dv\n-- 3 ThePrimeagen\n```\n\n\u003e NOTE: Length does not work over maps\n\n```lua\nlocal reading_scores = { msakiart = 10, teej_dv = \"N/A\" }\nfor index = 1, #reading_scores do\n    print(reading_scores[index])\nend\n-- This Doesn't print anything - the \"length\" of the array is 0.\n-- We aren't using it as an array, we're using it as a map!\n```\n\n- Use `pairs` to index inside hash tables\n\n```lua\nlocal reading_scores = { msakiart = 9.5, teej_dv = \"N/A\" }\nfor key, value in pairs(reading_scores) do\n    print(key, value)\nend\n-- Output\n-- msakiart 9.5\n-- teej_dv N/A\n```\n\n## Control Flow: `if`\n\n```lua\nlocal function action(loves_coffee)\n    if loves_coffee then\n        print(\"Check out `sh terminal.shop` - it's cool\")\n    else\n        print(\"Check out `sh terminal.shop` - it's still cool\")\n    end\nend\n\n-- \"falsey\": nil, false\naction() -- same as: action(nil)\naction(false)\n\n-- Everything else is \"truthy\"\naction(true)\naction(0)\naction({})\n\n-- Output\n-- Check out `sh terminal.shop` - it's still cool\n-- Check out `sh terminal.shop` - it's still cool\n-- Check out `sh terminal.shop` - it's cool\n-- Check out `sh terminal.shop` - it's cool\n-- Check out `sh terminal.shop` - it's cool\n```\n\n## Modules\n\nModules are just files. Nothing special about modules.\n\n```lua\n-- foo.lua\nlocal M = {}\nM.cool_function = function() end\nreturn M\n```\n\n```lua\n-- bar.lua\nlocal foo = require(\"foo\")\nfoo.cool_function()\n```\n\n## Function: Multiple Returns\n\n```lua\nlocal returns_four_variables = function()\n    return 1, 2, 3, 4\nend\n\nfirst, second, last = returns_four_variables()\n\nprint(\"first: \", first)\nprint(\"second: \", second)\nprint(\"last: \", last)\n-- the `4` is discarded :'(\n\n-- Output\n-- first: 1\n-- second: 2\n-- last: 3\n```\n\n- Value spreading ...\n    \u003e Some values can get lost when they are unpacked into other functions\n\n```lua\nlocal variable_arguments = function( ... )\n    local arguments = { ... }\n    for i, v in ipairs(arguments) do print(i,v) end\n    return unpack(arguments)\nend\n\nprint(\"===============\")\nprint(\"1:\", variable_arguments(\"hello\", \"world\", \"!\"))\nprint(\"===============\")\nprint(\"2:\", variable_arguments(\"hello\", \"world\", \"!\"), \"\u003clost\u003e\")\n\n-- Output\n-- ================\n-- 1: Hello\n-- 2: world\n-- 3: !\n-- 1: Hello world !\n-- ================\n-- 1: Hello\n-- 2: world\n-- 3: !\n-- 2: Hello \u003clost\u003e\n```\n\n## Functions: Calling\n\nString shorthand\n\n\u003e If the function takes a single string we can ignore the parentesis\n\n```lua\nlocal single_string = function(s)\n    return s .. \" - WOW!\"\nend\n\nlocal x = single_string(\"hi\")\nlocal y = single_string \"hi\"\nprint(x, y)\n-- Output\n-- hi - WOW !hi - WOW!\n```\n\nTable Shorthand\n\n```lua\nlocal setup = function(opts)\n    if opts.default == nil then\n        opts.default = 17\n    end\n\n    print(opts.default, opts.other)\nend\n\nsetup { default = 12, other = false }\nsetup { other = true }\n-- Output\n-- 12 false\n-- 17 true\n```\n\n## Functions: Colon Functions\n\nWhen we define a function on a table we can use the colon syntax:\n\n```lua\nlocal MyTable = {}\n\n-- Both these functions describe the same thing, creating a method in a table\nfunction MyTable.something(self, ... ) end\nfunction MyTable:something( ... ) end\n```\n\n## Metatables\n\nCan we add two tables in lua? ...\n\n\u003e If you want to add two tables you have to implement a `__add` method on the table\n\n```lua\nlocal vector_mt = {}\nvector_mt.__add = function(left, right)\n    return setmetatable({\n        left[1] + right[1],\n        left[2] + right[2],\n        left[3] + right[3],\n    }, vector_mt)\nend\n\nlocal v1 = setmetatable({ 3, 1, 5 }, vector_mt)\nlocal v2 = setmetatable({ -3, 2, 2 }, vector_mt)\nlocal v3 = v1 + v2\nvim.print(v3[1], v3[2], v3[3])\nvim.print(v3 + v3)\n-- Output\n-- 0 3 7\n-- 0 6 14, \u003cmetatable\u003e\n```\n\nImplement indexing inside a table ( metatables )\n\n```lua\nlocal fib_mt = {\n    __index = function(self, key)\n        if key \u003c 2 then return 1 end\n        -- Update the table, to save intermediate results ( caching )\n        self[key] = self[key - 2] + self[key - 1]\n        -- Return the result\n        return self[key]\n    end\n}\n\nlocal fib = setmetatable({}, fib_mt)\n\nprint(fib[5])\nprint(fib[1000])\n-- Output\n-- 7\n-- ~ 2 ** 208\n```\n\nOther notable fields (methods):\n\n- `__newindex(self, key, value)` - called by `__index` method\n- `__call(self, ... )` - allowss you to call a table as a function e.g. returns a state\n\n## Quick Neovim Goodies\n\nKeymappings to run lua code in nvim\n\n```lua\n-- press \u003cspace\u003e \u003cspace\u003e x in normal mode to run whole lua file\nvim.keymap.set(\"n\", \"\u003cspace\u003e\u003cspace\u003ex\", \"\u003ccmd\u003esource %\u003cCR\u003e\")\n-- press \u003cspace\u003e x in normal mode\nvim.keymap.set(\"n\", \"\u003cspace\u003ex\", \":.lua\u003cCR\u003e\")\n-- press \u003cspace\u003e x in visual mode to run lua snippet of code\nvim.keymap.set(\"v\", \"\u003cspace\u003ex\", \":lua\u003cCR\u003e\")\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmsaki%2Flua-tuorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmmsaki%2Flua-tuorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmsaki%2Flua-tuorial/lists"}