{"id":13896545,"url":"https://github.com/gustavo-hms/luar","last_synced_at":"2025-12-26T15:03:44.389Z","repository":{"id":47135063,"uuid":"261869084","full_name":"gustavo-hms/luar","owner":"gustavo-hms","description":"Script Kakoune using Lua","archived":false,"fork":false,"pushed_at":"2022-02-13T19:59:46.000Z","size":63,"stargazers_count":43,"open_issues_count":2,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-07T18:39:57.384Z","etag":null,"topics":["kakoune","lua","plugin"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gustavo-hms.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}},"created_at":"2020-05-06T20:17:13.000Z","updated_at":"2024-06-25T03:29:17.000Z","dependencies_parsed_at":"2022-09-05T09:30:35.413Z","dependency_job_id":null,"html_url":"https://github.com/gustavo-hms/luar","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gustavo-hms%2Fluar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gustavo-hms%2Fluar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gustavo-hms%2Fluar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gustavo-hms%2Fluar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gustavo-hms","download_url":"https://codeload.github.com/gustavo-hms/luar/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226265521,"owners_count":17597222,"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":["kakoune","lua","plugin"],"created_at":"2024-08-06T18:02:59.871Z","updated_at":"2025-12-26T15:03:44.380Z","avatar_url":"https://github.com/gustavo-hms.png","language":"Lua","funding_links":[],"categories":["Lua"],"sub_categories":[],"readme":"# Luar\n\nLuar is a minimalist plugin to script [Kakoune](http://kakoune.org/) using\neither [Lua](https://www.lua.org/) or [Fennel](https://fennel-lang.org/). It's\nnot designed to expose Kakoune's internals like\n[Vis](https://github.com/martanne/vis) or [Neovim](https://neovim.io/) do.\nInstead, it's conceived with Kakoune's extension model in mind. It does so by\ndefining a sole `lua` command which can execute whatever string is passed to it\nin an external `lua` interpreter, and an equivalent `fennel` command which\nexecutes whatever string is passed to it in an external `fennel` interpreter. By\ndoing so, it can act as a complement for the `%sh{}` expansion when you need to\nrun some logic inside Kakoune.\n\n## Usage\n\nFirst of all, require the provided module:\n\n```kak\nrequire-module luar\n```\n\nThe `luar` module exports a `lua` command, which executes the code passed to it in an external `lua` interpreter. The code is interpreted as the body of an anonymous function, and whatever this anonymous function returns replaces the current selections.\n\nSo, the following code:\n\n```lua\nlua %{\n    return \"Olá!\"\n}\n```\nreplaces your selections with `Olá!`.\n\nThe module also exposes a `fennel` command with the same semantics. See section\n[Executing fennel code](https://github.com/gustavo-hms/luar#executing-fennel-code) for some examples.\n\nIn the same vein, if you have, say, three selections, the code:\n\n```lua\nlua %{\n    return 17, 19, 23\n}\n```\n\nreplaces each selection with `17`, `19` and `23` respectivelly. The same can be achieved by returning a single table with three elements:\n\n\n```lua\nlua %{\n    return {17, 19, 23}\n}\n```\n\nThe two forms are equivalent.\n\nIf, on the other hand, you return nothing, the content of the selections won't be modified:\n\n```lua\nlua %{\n    if true then\n        return\n    end\n}\n```\n\nThe anonymous function can take arguments by passing values before the `%{}` block:\n\n```lua\nlua 17 19 %{\n    return arg[1] + arg[2]\n}\n```\n\nThe above code will replace all the selections with `36`. As you can see, the arguments can be accessed with the `arg` table.\n\nAs a convenience, you can use the provided `args` function to name your arguments:\n\n```lua\nlua 17 19 %{\n    local first, second = args()\n    return second - first\n}\n```\n\nSince Kakoune does not process expansions inside these `lua %{}` blocks, you need to pass expansions as arguments if you need to inspect Kakoune's state:\n\n```lua\nlua %val{client} %{\n    local client = args()\n    kak.echo(string.format(\"I'm client “%s”\", client))\n}\n```\n\n## Calling commands\n\nYou can run all commands defined in Kakoune (including third party ones) from `lua` code using the provided `kak` module:\n\n```kak\ndefine-command custom-echo -params 1.. %{\n    echo %arg{@}\n}\n\nlua %{\n    kak.set_register(\"/\", \"Search this!\")\n    kak.execute_keys('%s\u003cret\u003ecSearch that!\u003cesc\u003e')\n    -- Calling custom commands is also possible.\n    kak.custom_echo(\"Text selected!\")\n}\n```\nAs you can see, hyphens are replaced by underscores in command names. Luar also takes care of quoting the arguments to avoid unexpected results.\n\n## Executing fennel code\n\nAnything you can do with the `lua` command you can do with the equivalent `fennel` command. So, to replace your selections with the string `\"Olá!\"`:\n```fennel\nfennel %{\n  \"Olá!\"\n}\n```\nOr, to replace three selections with some numbers:\n```fennel\nfennel %{\n  (values 17 19 23)\n}\n```\n\nExpansions work the same way:\n\n```fennel\nfennel %val{client} %{\n  (let [client (args)]\n    (kak.echo (string.format \"I'm client “%s”\" client)))\n}\n```\n\nThe only difference is that you don't need to replace hyphens with underscores in command names:\n\n```kak\ndefine-command custom-echo -params 1.. %{\n    echo %arg{@}\n}\n\nfennel %{\n    (kak.set-register \"/\" \"Search this!\")\n    (kak.execute-keys \"%s\u003cret\u003ecSearch that!\u003cesc\u003e\")\n    (kak.custom-echo \"Text selected!\")\n}\n```\n\n## External modules\n\nSince Lua modules are just plain tables and `require` is just a simple function, you can import modules everywhere in your program, not just at the beginning of a file. In particular, you can import external modules inside the `:lua` command. For instance, if you need to parse the contents of a file, you can use the elegant [LPeg](http://www.inf.puc-rio.br/~roberto/lpeg/) library:\n\n```lua\nlua %val{buffile} %{\n    local lpeg = require \"lpeg\"\n\n    local function parse(file)\n        -- do the lpeg's magic here\n    end\n\n    local tree = parse(arg[1])\n    -- ...\n}\n```\n\nYou can also use this functionality to split your plugin into separate modules\nand use `:lua` to glue them together. To make that easier, `luar` provides the\n`addpackagepath` convenience function. It configures the lua interpreter to\nsearch for lua modules in the provided directory. It's meant to be used like\nthis:\n\n```kak\ndeclare-option -hidden str my_plugin_path %sh{ dirname $kak_source }\n\ndefine-command my-command %{\n    lua %opt{my_plugin_path} %{\n        addpackagepath(arg[1])\n        local module = require \"my_local_module\"\n        -- ...\n    }\n}\n```\n\n## Debugging\n\nPassing the `-debug` flag, the `luar` command will print in the `*debug*` buffer all Kakoune commands it would otherwise execute. This way, you can see the exact commands your script would execute. For instance, running\n\n```kak\nlua -debug %val{client} %{\n    local keys = \"%ssomethingcanything\u003cret\u003e\"\n    kak.execute_keys(keys)\n    kak.echo(\"Word something replaced by word anything on client \" .. arg[1])\n    kak.write()\n}\n```\nwould print the following text in the debug buffer:\n```\nluar: execute-keys %☾%ssomethingcanything\u003cret\u003e☾\nluar: echo %☾Word something replaced by word anything on client client0☾\nluar: write\n```\n\n## Some examples\nThe following examples are for didactic purposes. There are other ways to achieve the same results.\n\nSuppose you want to execute `ctags-update-tags` whenever you write to a file, but only if there's already a `tags` file in the current directory. Using `:lua` you can write the following lines to your `kakrc`:\n\n```lua\nhook global BufWritePost .* %{\n    lua %{\n        if io.open(\"tags\") then kak.ctags_update_tags() end\n    }\n}\n```\n\nNow suppose you want to define a mapping to toggle the highlight of search patterns in the current window when you press `F2`. To achieve that, you can do something like this:\n\n```lua\ndeclare-option -hidden bool highlight_search_on false\n\ndefine-command highlight-search-toggle %{\n    lua %opt{highlight_search_on} %{\n        local is_on = args()\n\n        if is_on then\n            kak.remove_highlighter(\"window/highlight-search\")\n        else\n            kak.add_highlighter(\"window/highlight-search\", \"dynregex\", \"%reg{/}\", \"0:default,+ub\")\n        end\n\n        kak.set_option(\"window\", \"highlight_search_on\", not is_on)\n    }\n}\n\nmap global normal \u003cF2\u003e ': highlight-search-toggle\u003cret\u003e'\n```\n\nYou can find more examples [searching Github by topic](https://github.com/search?q=topic%3Akakoune+topic%3Aplugin+topic%3Alua).\n\n## Installation\n\nYou must have a `lua` interpreter installed on your system.\n\nThen, if you use [Almoxarife](https://github.com/gustavo-hms/almoxarife), add this to its configuration file:\n\n```yaml\nluar:\n  location: https://github.com/gustavo-hms/luar\n```\n\nOr, if you use [kak-bundle](https://codeberg.org/jdugan6240/kak-bundle), add this to your `kakrc`:\n\n```kak\nbundle luar \"gustavo-hms/luar\"\n```\n\n## Configuration\n\nYou can also change the Lua interpreter used by this plugin by changing the `luar_interpreter` option, e.g.:\n\n```kak\n# use luajit to run all Lua snippets\nset-option global luar_interpreter luajit\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgustavo-hms%2Fluar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgustavo-hms%2Fluar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgustavo-hms%2Fluar/lists"}