├── .gitignore ├── LICENSE ├── README.md ├── dev └── init.lua ├── doc └── presentation.md └── lua └── greetings ├── awesome-module.lua └── init.lua /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Lua sources 2 | luac.out 3 | 4 | # luarocks build files 5 | *.src.rock 6 | *.zip 7 | *.tar.gz 8 | 9 | # Object files 10 | *.o 11 | *.os 12 | *.ko 13 | *.obj 14 | *.elf 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | *.def 26 | *.exp 27 | 28 | # Shared objects (inc. Windows DLLs) 29 | *.dll 30 | *.so 31 | *.so.* 32 | *.dylib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | *.i*86 39 | *.x86_64 40 | *.hex 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 s1n7ax 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # neovim-lua-plugin-boilerplate 2 | 3 | I forget the structure of a `neovim` plugin every single time. So I created the 4 | boilerplate to make it easier to get started writing `neovim` plugin. 5 | 6 | [YouTube video](https://youtu.be/6ch28A_YICQ) 7 | 8 | ## How to use 9 | 10 | * clone the project `git clone https://github.com/s1n7ax/neovim-lua-plugin-boilerplate` 11 | * go to the project folder `cd neovim-lua-plugin-boilerplate` 12 | * start editing `nvim --cmd "set rtp+=."` 13 | * reference the dev configurations `:luafile dev/init.lua` 14 | * run the greetings.greet() function using `,w` keybind 15 | -------------------------------------------------------------------------------- /dev/init.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | -- plugin name will be used to reload the loaded modules 3 | --]] 4 | local package_name = 'greetings' 5 | 6 | -- add the escape character to special characters 7 | local escape_pattern = function (text) 8 | return text:gsub("([^%w])", "%%%1") 9 | end 10 | 11 | -- unload loaded modules by the matching text 12 | local unload_packages = function () 13 | local esc_package_name = escape_pattern(package_name) 14 | 15 | for module_name, _ in pairs(package.loaded) do 16 | if string.find(module_name, esc_package_name) then 17 | package.loaded[module_name] = nil 18 | end 19 | end 20 | end 21 | 22 | -- executes the run method in the package 23 | local run_action = function () 24 | require(package_name).greet() 25 | end 26 | 27 | -- unload and run the function from the package 28 | function Reload_and_run() 29 | unload_packages() 30 | run_action() 31 | end 32 | 33 | local set_keymap = vim.api.nvim_set_keymap 34 | 35 | set_keymap('n', ',r', 'luafile dev/init.lua', {}) 36 | set_keymap('n', ',w', 'lua Reload_and_run()', {}) 37 | -------------------------------------------------------------------------------- /doc/presentation.md: -------------------------------------------------------------------------------- 1 | # Neovim-Lua Plugin Development Beginner's Guide 2 | 3 | ## Before we start 4 | 5 | * Neovim Lua boilerplate: https://github.com/s1n7ax/neovim-lua-plugin-boilerplate 6 | * Neovim Lua video tutorials: https://youtube.com/playlist?list=PL0EgBggsoPCk1WCos2txThsxhg0fT5nqD 7 | * My Neovim configuration: https://github.com/s1n7ax/dotnvim 8 | * Terminal manager: https://github.com/s1n7ax/nvim-terminal 9 | 10 | ## Prerequisites 11 | 12 | * Neovim 0.5 or higher version 13 | * Git 14 | * GitHub Account 15 | 16 | ## Setting up the project 17 | 18 | * Create GitHub project 19 | * Clone the project 20 | 21 | ```bash 22 | git clone 23 | ``` 24 | 25 | * Open Neovim for editing 26 | 27 | ``` 28 | # NOTE: make sure to add current directory to runtime path 29 | # otherwise, Neovim does not know how to find your plugin 30 | nvim --cmd "set rtp+=." 31 | ``` 32 | 33 | * Create Lua module in Lua source directory 34 | 35 | ```bash 36 | mkdir -p lua/greetings 37 | ``` 38 | 39 | * Create init file and sub modules for the module 40 | 41 | ```bash 42 | touch lua/greetings/init.lua 43 | touch lua/greetings/awesome-module.lua 44 | ``` 45 | 46 | ## Create greetings plugin 47 | 48 | * Add greet function to `awesome-module.lua` 49 | 50 | ```lua 51 | local function greet() 52 | print('testing') 53 | end 54 | 55 | return greet 56 | ``` 57 | 58 | * Expose public APIs of the plugin 59 | 60 | ```lua 61 | local greet = require('greetings.awesome-module') 62 | 63 | return { 64 | greet = greet 65 | } 66 | ``` 67 | 68 | * Testing plugin APIs 69 | 70 | ```vim 71 | # you should run this in the vim command line 72 | :lua require('greetings').greet() 73 | ``` 74 | 75 | ## Few tips when developing plugins 76 | 77 | ### See changes without re opening Neovim 78 | 79 | Lua will not reload module if it already exists. The changes you made will be 80 | applied the next time you open the editor. But you can force Lua to reload the 81 | module for development. 82 | 83 | * Create `dev/init.lua` file 84 | 85 | ```bash 86 | mkdir -p dev 87 | touch dev/init.lua 88 | ``` 89 | 90 | * Add following to `dev/init.lua` to force reloading 91 | 92 | ``` 93 | -- force lua to import the modules again 94 | package.loaded['dev'] = nil 95 | package.loaded['greetings'] = nil 96 | package.loaded['greetings.awesome-module'] = nil 97 | 98 | -- [ , + r ] keymap to reload the lua file 99 | -- NOTE: someone need to source this file to apply these configurations. So, the 100 | -- very first time you open the project, you have to source this file using 101 | -- ":luafile dev/init.lua". From that point onward, you can hit the keybind to 102 | -- reload 103 | vim.api.nvim_set_keymap('n', ',r', 'luafile dev/init.lua', {}) 104 | ``` 105 | 106 | * While we are in the file, lets add shortcut to run the greeting plugin 107 | 108 | ```lua 109 | -- keybind to test the plugin 110 | Greetings = require('greetings') 111 | vim.api.nvim_set_keymap('n', ',w', 'lua Greetings.greet()', {}) 112 | ``` 113 | 114 | 115 | ## Learn more about Neovim-Lua 116 | 117 | * I release a video on YouTube once a year XD. [This is the link to playlist.](https://youtube.com/playlist?list=PL0EgBggsoPCk1WCos2txThsxhg0fT5nqD) You can subscribe to the channel too ;) 118 | * [nvim-lua-guide](https://github.com/nanotee/nvim-lua-guide) is awesome place 119 | to start learning Neovim-Lua APIs 120 | * Run `:h api` in Neovim to get all available Neovim-Lua APIs 121 | * Run `:h function` to learn about vim functions. You can run vim functions 122 | using `vim.fn.()` 123 | * Use [Neovim subreddit](https://www.reddit.com/r/neovim) to stay updated and ask questions 124 | -------------------------------------------------------------------------------- /lua/greetings/awesome-module.lua: -------------------------------------------------------------------------------- 1 | local function greet() 2 | print('hello world') 3 | end 4 | 5 | return greet 6 | -------------------------------------------------------------------------------- /lua/greetings/init.lua: -------------------------------------------------------------------------------- 1 | local greet = require('greetings.awesome-module') 2 | 3 | return { 4 | greet = greet 5 | } 6 | --------------------------------------------------------------------------------