{"id":13896862,"url":"https://github.com/famiclone/nvim-lua-guide-ua","last_synced_at":"2025-07-17T13:31:30.398Z","repository":{"id":46757591,"uuid":"515071292","full_name":"famiclone/nvim-lua-guide-ua","owner":"famiclone","description":null,"archived":false,"fork":false,"pushed_at":"2022-07-21T20:39:55.000Z","size":13,"stargazers_count":14,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-08-07T18:41:35.058Z","etag":null,"topics":["guide","neovim","neovim-lua","ukrainian","ukrainian-language","vim"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/famiclone.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-18T07:04:08.000Z","updated_at":"2024-02-23T13:22:39.000Z","dependencies_parsed_at":"2022-09-24T08:30:28.927Z","dependency_job_id":null,"html_url":"https://github.com/famiclone/nvim-lua-guide-ua","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/famiclone%2Fnvim-lua-guide-ua","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/famiclone%2Fnvim-lua-guide-ua/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/famiclone%2Fnvim-lua-guide-ua/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/famiclone%2Fnvim-lua-guide-ua/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/famiclone","download_url":"https://codeload.github.com/famiclone/nvim-lua-guide-ua/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226265524,"owners_count":17597223,"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":["guide","neovim","neovim-lua","ukrainian","ukrainian-language","vim"],"created_at":"2024-08-06T18:03:12.293Z","updated_at":"2024-11-25T02:31:22.726Z","avatar_url":"https://github.com/famiclone.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# Початок роботи з Lua в Neovim\n\n## Інші переклади\n\n- [:uk: English version](https://github.com/nanotee/nvim-lua-guide)\n- [:cn: Chinese version](https://github.com/glepnir/nvim-lua-guide-zh)\n- [:es: Spanish version](https://github.com/RicardoRien/nvim-lua-guide/blob/master/README.esp.md)\n- [:brazil: Portuguese version](https://github.com/npxbr/nvim-lua-guide/blob/master/README.pt-br.md)\n- [:jp: Japanese version](https://github.com/willelz/nvim-lua-guide-ja/blob/master/README.ja.md)\n- [:ru: Russian version](https://github.com/kuator/nvim-lua-guide-ru)\n\n## Зміст\n\n- [Початок](#початок)\n  - [Вивчення Lua](#вивчення-lua)\n  - [Існуючі туторіали](#існуючі-туторіали-по-написанню-lua-в-neovim)\n  - [Допоміжні плагіни](#допоміжні-плагіни)\n- [Куди класти Lua файли](#куди-класти-lua-файли)\n  - [init.lua](#initlua)\n  - [Модулі](#модулі)\n    - [Поради](#поради)\n  - [Файли рантайму](#файли-рантайму)\n    - [Поради](#поради)\n- [Використання Lua у Vimscript](#використання-lua-у-vimscript)\n  - [:lua](#lua)\n  - [:luado](#luado)\n  - [Підключення Lua файлів](#підключення-lua-файлів)\n    - [Різниця між підключенням та викликом require()](#різниця-між-підключенням-та-викликом-require)\n  - [luaeval()](#luaeval)\n  - [v:lua](#vlua)\n    - [Застереження](#застереження)\n  - [Поради](#поради)\n- [Простір імен vim](#простір-імен-vim)\n  - [Поради](#поради)\n\n## Початок\n\n[Інтеграція Lua](https://www.youtube.com/watch?v=IP3J56sKtn0) в якості [першокласної мови всередині Neovim](https://github.com/neovim/neovim/wiki/FAQ#why-embed-lua-instead-of-x) перетворює її в одну із найважливіших особливостей. Тим не менш, кількість учбових матеріалів по розробці плагінів на Lua значно менше ніж аналогічних матеріалів на Vimscript. Цей довідник спроба надати базову інформацію для початку.\n\n\u003e Довідник написаний з припущенням, що ви використовуєте що найменш 0.5 версію Neovim.\n\n### Вивчення Lua\n\nЯкщо ви ще не знайомі з цією мовою програмування, є велике різноманіття ресурсів щоб почати:\n\n- [Learn X in Y minutes page about Lua](https://learnxinyminutes.com/docs/lua/) надасть вам швидкий огляд основи мови\n- [Цей гайд](https://github.com/medwatt/Notes/blob/main/Lua/Lua_Quick_Guide.ipynb) також добрий ресурс для швидкого початку\n- Якщо вам більше подобаються відео, [1-hour tutorial on the language](https://www.youtube.com/watch?v=iMacxZQMPXs)\n- Потрібно більше інтерактивних прикладів? Спробуй [the LuaScript tutorial](https://www.luascript.dev/learn)\n- [Lua-users wiki](http://lua-users.org/wiki/LuaDirectory) великий обсяг корисної інформації по Lua\n- [Official reference manual for Lua](https://www.lua.org/manual/5.1/) може дати тобі найкомплексний огляд мови (Є Vimdoc плагін для читання всередині Neovim: [milisims/nvim-luaref](https://github.com/milisims/nvim-luaref))\n\nСлід зазначити що Lua дуже проста мова програмування. Її легко вчити, особливо якщо ви маєте досвід зі схожими мовами - наприклад Javscript. Ви можете знати Lua більше ніж вважаєте!\n\n\u003e Інтегрована версія Lua у Neovim [LuaJIT](https://staff.fnwi.uva.nl/h.vandermeer/docs/lua/luajit/luajit_intro.html) 2.1.0, що підтримує сумісність з Lua 5.1.\n\n### Існуючі туторіали по написанню Lua в Neovim\n\nДекілька туторіалів вже написані щоб допомогти розроблювати Lua плагіни для Neovim. Деякі з них трохи допомогли написати цей довідник. Велика вдячність авторам.\n\n- [teukka.tech - From init.vim to init.lua](https://teukka.tech/luanvim.html)\n- [dev.to - How to write neovim plugins in Lua](https://dev.to/2nit/how-to-write-neovim-plugins-in-lua-5cca)\n- [dev.to - How to make UI for neovim plugins in Lua](https://dev.to/2nit/how-to-make-ui-for-neovim-plugins-in-lua-3b6e)\n- [ms-jpq - Neovim Async Tutorial](https://github.com/ms-jpq/neovim-async-tutorial)\n- [oroques.dev - Neovim 0.5 features and the switch to init.lua](https://oroques.dev/notes/neovim-init/)\n- [Building A Vim Statusline from Scratch - jdhao's blog](https://jdhao.github.io/2019/11/03/vim_custom_statusline/)\n- [Configuring Neovim using Lua](https://icyphox.sh/blog/nvim-lua/)\n- [Devlog | Everything you need to know to configure neovim using lua](https://vonheikemen.github.io/devlog/tools/configuring-neovim-using-lua/)\n\n### Допоміжні плагіни\n\n- [Vimpeccable](https://github.com/svermeulen/vimpeccable) - Допоміжний плагін для написання `.vimrc` на Lua\n- [plenary.nvim](https://github.com/nvim-lua/plenary.nvim) - Плагін, щоб не писати всі функції Lua двічі\n- [popup.nvim](https://github.com/nvim-lua/popup.nvim) - Імплементація Popup API з vim\n- [nvim_utils](https://github.com/norcalli/nvim_utils) - Допоміжні утіліти\n- [nvim-luadev](https://github.com/bfredl/nvim-luadev) - REPL/дебаг консоль для розробки Lua плагінів\n- [nvim-luapad](https://github.com/rafcamlet/nvim-luapad) - Інтерактивна пісочниця для вбудованого Lua\n- [nlua.nvim](https://github.com/tjdevries/nlua.nvim) - Lua розробка для Neovim\n- [BetterLua.vim](https://github.com/euclidianAce/BetterLua.vim) - Краще підсвічування синтаксису Lua у Vim/NeoVim\n\n## Куди класти Lua файли\n\n### init.lua\n\nNeovim підтримує здатність використовувати конфіги написані на Lua - `init.lua`, окрім звичного `init.vim`\n\n\u003e `init.lua` звісно **опціональний** формат для конфігурації. Підтримка `init.vim` не зникла, та може використовуватись разом з Lua-конфігом. Також поки що не всі функції редактора підтримуються через Lua.\n\nДивіться також:\n\n- [`:help config`](https://neovim.io/doc/user/starting.html#config)\n\n### Модулі\n\nLua модулі можна знайти всередині `lua/` директорії в вашому `'runtimepath'` (для більшості юзерів це буде `~/.config/nvim/lua` на \\*nix системах та `~/AppData/Local/nvim/lua` на Windows. За допомогою функції `require()` ви можете імпортити модулі з ціеї директорії.\n\nДавайте розглянемо структуру директорій:\n\n```text\n📂 ~/.config/nvim\n├── 📁 after\n├── 📁 ftplugin\n├── 📂 lua\n│  ├── 🌑 myluamodule.lua\n│  └── 📂 other_modules\n│     ├── 🌑 anothermodule.lua\n│     └── 🌑 init.lua\n├── 📁 pack\n├── 📁 plugin\n├── 📁 syntax\n└── 🇻 init.vim\n```\n\nНаступний код завантажить `myluamodule.lua`:\n\n```lua\nrequire('myluamodule')\n```\n\nМожете не вказувати розширення `.lua`.\nСхожим чином завантаження `other_modules/anothermodule.lua` виглядає так:\n\n```lua\nrequire('other_modules.anothermodule')\n```\n\nабо\n\n```lua\nrequire('other_modules/anothermodule')\n```\n\nРозділителі шляху можуть бути крапкою `.` або слешем `/`.\n\nЯкщо ви намагаєтесь завантажити не існуючий модуль, це призведе до помилки та відміни виконання скрипта.\n`pcall()` функція може бути використана для запобігання помилок.\n\n```lua\nlocal ok, _ = pcall(require, 'module_with_error')\nif not ok then\n  -- не заванжувати\nend\n```\n\nДивіться також:\n\n- [`:help lua-require`](https://neovim.io/doc/user/lua.html#lua-require)\n\n#### Поради\n\nДеякі плагіни можуть мати однакові імена файлів у `lua/` директорії. Це може призвести до конфлікту простору імен.\n\nЯкщо два різних плагіни мають файл `lua/main.lua`, а потім завантажуються шляхом `require('main')`, то який з них буде використаний?\n\nТому буде гарною ідеєю покласти кожен `main.lua` файл у діректорію з назвою плагіну: `lua/plugin_name/main.lua`\n\n### Файли рантайму\n\nЯк і Vimscript файли, Lua файли можуть бути завантажені автоматично зі спеціальної директорії `runtimepath`. На даний час підтримуються наступні назви директорій:\n\n- `colors/`\n- `compiler/`\n- `ftplugin/`\n- `ftdetect/`\n- `indent/`\n- `plugin/`\n- `syntax/`\n\n\u003e У рантайм директорії, усі `*.vim` файли мають бути визвані після `*.lua` файлів.\n\nДивіться також:\n\n- [`:help 'runtimepath'`](https://neovim.io/doc/user/options.html#'runtimepath')\n- [`:help load-plugins`](https://neovim.io/doc/user/starting.html#load-plugins)\n\n#### Поради\n\nПоки файли рантайму не базуються на системі модулів Lua, два плагіни можуть мати файл `plugin/main.lua` без проблем.\n\n## Використання Lua у Vimscript\n\n### :lua\n\nЦя команда виконує шматок Lua коду.\n\n```lua\n:lua require('myluamodule')\n```\n\nЗа допомогою heredoc синтаксису можливо виконувати багаторядкові скріпти:\n\n```vim\necho \"Here's a bigger chunk of Lua code\"\n\nlua \u003c\u003c EOF\nlocal mod = require('mymodule')\nlocal tbl = {1, 2, 3}\n\nfor k, v in ipairs(tbl) do\n    mod.method(v)\nend\n\nprint(tbl)\nEOF\n```\n\n\u003e Кожна `lua` команда має свою область бачення та змінні оголошені з ключовим словом `local` не будуть доступні за межами команди. Приклад:\n\n```vim\n:lua local foo = 1\n:lua print(foo)\n\" виведе 'nil' замість '1'\n```\n\n\u003e Lua функція `print()` поводиться схоже до `:echomsg` команди. Вихідні дані будуть збережені у історіі повідомлень.\n\nДивіться також:\n\n- [`:help :lua`](https://neovim.io/doc/user/lua.html#Lua)\n- [`:help :lua-heredoc`](https://neovim.io/doc/user/lua.html#:lua-heredoc)\n\n### :luado\n\nЦя команда виконує шматок Lua коду який діє на діапазон рядків у поточному буфері. Якщо рядки не зазначені, то для цілого буферу. Будь-який рядок який повернувся з блоку, використовується для визначення того, чим слід замінити кожен рядок.\n\nНаступна команда замінила би кожен рядок у поточному буфері текстом `hello world`:\n\n```vim\n:luado return 'hello world'\n```\n\nДві неявні змінні `line` та `linenr` також доступні. `line` – це текст рядка, а `linenr` – номер. Наступна команда зробить кожен рядок у верхньому регістрі, якщо номер рядка ділиться на 2 без залишку:\n\n```vim\n:luado if linenr % 2 == 0 then return line:upper() end\n```\n\nДивіться також:\n\n- [`:help :luado`](https://neovim.io/doc/user/lua.html#:luado)\n\n### Підключення Lua файлів\n\nNeovim надає 3 Ex команди щоб підключити Lua файли:\n\n- `:luafile`\n- `:source`\n- `:runtime`\n\n`:luafile` та `:source` дуже схожі:\n\n```vim\n:luafile ~/foo/bar/baz/myluafile.lua\n:luafile %\n:source ~/foo/bar/baz/myluafile.lua\n:source %\n```\n\n`:source` також підтримує діапазони, котрі будуть корисні для виконання частини скрипту:\n\n```vim\n:1,10source\n```\n\nКоманда `runtime` дещо відрізняється: вона використовує `'runtimepath'` опцію для визначення директорії звідки будуть підключені файли. Більшe деталей: [`:help :runtime`](https://neovim.io/doc/user/repeat.html#:runtime).\n\nДивіться також:\n\n- [`:help :luafile`](https://neovim.io/doc/user/lua.html#:luafile)\n- [`:help :source`](https://neovim.io/doc/user/repeat.html#:source)\n- [`:help :runtime`](https://neovim.io/doc/user/repeat.html#:runtime)\n\n#### Різниця між підключенням та викликом require():\n\nМожливо вам цікаво у чому різниця та чи варто віддавати перевагу одному способу над іншим. Вони мають різні випадки використання:\n\n- `require()`:\n  - вбудована функція Lua. Дозволяє користуватися перевагами модульної системи Lua\n  - шукає модулі у директорії `lua/` у вашому `'runtimepath'`\n  - дозволяє слідкувати за тим які модулі були завантажені та запобігає повторному парсингу та виконанню скрипта. Якщо ви зміните код у вже завантаженому модулі та спробуєте завантажити його через `require()` ще раз, то зміни не застосуються.\n- `:luafile`, `:source`, `:runtime`:\n  - Ex команди. Не підтримують модулі\n  - повторно виконують раніше виконані скрипти\n  - `:luafile` та `:source` приймають шлях до файлу як абсолютний так і відносний до робочої директорії поточного вікна\n  - `:runtime` використовує `'runtimepath'` опцію щоб знайти файли\n\n### luaeval()\n\nЦя вбудована Vimscript функція виконує Lua вираження та повертає результат. Типи данних Lua автоматично конвертуються у Vimscript типи (і навпаки).\n\n```vim\n\" You can store the result in a variable\nlet variable = luaeval('1 + 1')\necho variable\n\" 2\nlet concat = luaeval('\"Lua\"..\" is \"..\"awesome\"')\necho concat\n\" 'Lua is awesome'\n\n\" List-like tables are converted to Vim lists\nlet list = luaeval('{1, 2, 3, 4}')\necho list[0]\n\" 1\necho list[1]\n\" 2\n\" Note that unlike Lua tables, Vim lists are 0-indexed\n\n\" Dict-like tables are converted to Vim dictionaries\nlet dict = luaeval('{foo = \"bar\", baz = \"qux\"}')\necho dict.foo\n\" 'bar'\n\n\" Same thing for booleans and nil\necho luaeval('true')\n\" v:true\necho luaeval('nil')\n\" v:null\n\n\" You can create Vimscript aliases for Lua functions\nlet LuaMathPow = luaeval('math.pow')\necho LuaMathPow(2, 2)\n\" 4\nlet LuaModuleFunction = luaeval('require(\"mymodule\").myfunction')\ncall LuaModuleFunction()\n\n\" It is also possible to pass Lua functions as values to Vim functions\nlua X = function(k, v) return string.format(\"%s:%s\", k, v) end\n```\n\n`luaeval()` приймає опціональний другий аргумент який дозволяє передавати дані до вираження. Потім у вас буде доступ до данних через магічну глобальну змінну `_A`:\n\n```vim\necho luaeval('_A[1] + _A[2]', [1, 1])\n\" 2\n\necho luaeval('string.format(\"Lua is %s\", _A)', 'awesome')\n\" 'Lua is awesome'\n```\n\nДивіться також:\n\n- [`:help luaeval()`](\u003chttps://neovim.io/doc/user/lua.html#luaeval()\u003e)\n\n### v:lua\n\nЦе глобальна Vim змінна дозволяє вам викликати Lua функції у глобальному просторі імен ([`_G`](https://www.lua.org/manual/5.1/manual.html#pdf-_G)) напряму з Vimscript. І знову типи данних Vim будуть сконвертовані у Lua типи і навпаки.\n\n```vim\ncall v:lua.print('Hello from Lua!')\n\" 'Hello from Lua!'\n\nlet scream = v:lua.string.rep('A', 10)\necho scream\n\" 'AAAAAAAAAA'\n\n\" How about a nice statusline?\nlua \u003c\u003c EOF\n\n\" How about a nice statusline?\nlua \u003c\u003c EOF\nfunction _G.statusline()\n    local filepath = '%f'\n    local align_section = '%='\n    local percentage_through_file = '%p%%'\n    return string.format(\n        '%s%s%s',\n        filepath,\n        align_section,\n        percentage_through_file\n    )\nend\nEOF\n\nset statusline=%!v:lua.statusline()\n\n\" Also works in expression mappings\nlua \u003c\u003c EOF\nfunction _G.check_back_space()\n    local col = vim.api.nvim_win_get_cursor(0)[2]\n    return (col == 0 or vim.api.nvim_get_current_line():sub(col, col):match('%s')) and true\nend\nEOF\n\ninoremap \u003csilent\u003e \u003cexpr\u003e \u003cTab\u003e\n    \\ pumvisible() ? \"\\\u003cC-N\u003e\" :\n    \\ v:lua.check_back_space() ? \"\\\u003cTab\u003e\" :\n    \\ completion#trigger_completion()\n\n\" Call a function from a Lua module by using single quotes and omitting parentheses:\ncall v:lua.require'module'.foo()\n```\n\nДивіться також:\n\n- [`:help v:lua`](https://neovim.io/doc/user/eval.html#v:lua)\n- [`:help v:lua-call`](https://neovim.io/doc/user/lua.html#v:lua-call)\n\n#### Застереження\n\nЦя змінна може бути використана тільки для виклику функцій. Наступний код завжди буде викидувати помилку:\n\n```vim\n\" Aliasing functions doesn't work\nlet LuaPrint = v:lua.print\n\n\" Accessing dictionaries doesn't work\necho v:lua.some_global_dict['key']\n\n\" Using a function as a value doesn't work\necho map([1, 2, 3], v:lua.global_callback)\n```\n\n### Поради\n\nВи можете увімкнути підсвічення синтаксису Lua всередині `.vim` файлів. Додайте `let g:vimsyn_embed = 'l'` до вашого файлу конфігурації. Більше інформаціЇ [`:help g:vimsyn_embed`](https://neovim.io/doc/user/syntax.html#g:vimsyn_embed).\n\n## Простір імен vim\n\nNeovim має глобальну змінну `vim` яка є вхідною точкою до API з Lua коду. Це надає користувачам розширену стандартну бібліотеку функцій, а також різноманітні підмодулі.\n\nДеякі важливі функції та модулі:\n\n- `vim.inspect`: трансформує Lua обʼєкти до людино-зрозумілий вигляду (корисно для інспектування Lua таблиць)\n- `vim.regex`: використовуйте регулярні вираження vim із Lua\n- `vim.api`: модуль який надає доступ до API функцій (також використовується віддаленими плагінами)\n- `vim.ui`: UI функції\n- `vim.loop`: модуль для доступу до event-loop (використовує LibUV)\n- `vim.lsp`: модуль що контролює вбудований LSP клієнт\n- `vim.treesitter`: модуль для доступу до функціоналу бібліотеки tree-sitter\n\nЦей список не є вичерпним. Якщо ви бажаєте знати що доступно через `vim` змінну, [`:help lua-stdlib`](https://neovim.io/doc/user/lua.html#lua-stdlib) та [`:help lua-vim`](https://neovim.io/doc/user/lua.html#lua-vim). Додатково, ви можете використовувати команду `:lua print(vim.inspect(vim))` щоб отримати повний список модулів. API функції теж документовані [`:help api-global`](https://neovim.io/doc/user/api.html#api-global).\n\n#### Поради\n\nПисати `print(vim.inspect(x))` кожен раз коли треба проінспектувати вміст обʼєкта може бути нудним процесом. Можливо, варто мати глобальну обгортку десь у файлі конфігурації (у Neovim 0.7.9+, ця функція вбудована, більше інформації [`:help vim.pretty_print()`](\u003chttps://neovim.io/doc/user/lua.html#vim.pretty_print()\u003e)):\n\n```lua\nfunction _G.put(...)\n  local objects = {}\n  for i = 1, select('#', ...) do\n    local v = select(i, ...)\n    table.insert(objects, vim.inspect(v))\n  end\n\n  print(table.concat(objects, '\\n'))\n  return ...\nend\n```\n\nYou can then inspect the contents of an object very quickly in your code or from the command-line:\nТепер ви можете інспектувати вміст обʼєкту швидко у вашому коді чи через командний рядок:\n\n```lua\nput({1, 2, 3})\n```\n\n```vim\n:lua put(vim.loop)\n```\n\nДодатково ви можете використовувати `:lua` команду для красиво вивести вираження додавши до нього префікс `=` (Neovim 0.7+)\n\n```vim\n:lua =vim.loop\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffamiclone%2Fnvim-lua-guide-ua","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffamiclone%2Fnvim-lua-guide-ua","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffamiclone%2Fnvim-lua-guide-ua/lists"}