From 265ea97b1153ed0020549a081045ce5a01a01b79 Mon Sep 17 00:00:00 2001 From: S1M0N38 Date: Fri, 9 Feb 2024 13:28:11 +0100 Subject: [PATCH] Initial commit --- .github/ISSUE_TEMPLATE/bug_report.yml | 54 +++++++ .github/ISSUE_TEMPLATE/feature_request.yml | 36 +++++ .github/workflows/docs.yml | 61 ++++++++ .github/workflows/lint.yml | 27 ++++ .github/workflows/release.yml | 40 ++++++ .github/workflows/test.yml | 47 ++++++ .luacheckrc | 37 +++++ .neoconf.json | 9 ++ .stylua.toml | 6 + LICENSE | 21 +++ Makefile | 28 ++++ README.md | 103 +++++++++++++ doc/.gitkeep | 0 doc/my_awesome_plugin.txt | 136 ++++++++++++++++++ lua/my_awesome_plugin/config.lua | 32 +++++ lua/my_awesome_plugin/init.lua | 60 ++++++++ lua/my_awesome_plugin/math.lua | 43 ++++++ plugin/my_awesome_plugin.lua | 8 ++ scripts/docs.lua | 34 +++++ scripts/minimal_init.vim | 7 + .../my_awesome_plugin_spec.lua | 27 ++++ 21 files changed, 816 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/workflows/docs.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/test.yml create mode 100644 .luacheckrc create mode 100644 .neoconf.json create mode 100644 .stylua.toml create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 doc/.gitkeep create mode 100644 doc/my_awesome_plugin.txt create mode 100644 lua/my_awesome_plugin/config.lua create mode 100644 lua/my_awesome_plugin/init.lua create mode 100644 lua/my_awesome_plugin/math.lua create mode 100644 plugin/my_awesome_plugin.lua create mode 100644 scripts/docs.lua create mode 100644 scripts/minimal_init.vim create mode 100644 tests/my_awesome_plugin/my_awesome_plugin_spec.lua diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..df536b1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,54 @@ +name: Bug Report +description: File a bug/issue +title: "bug: " +labels: [bug] +body: + - type: markdown + attributes: + value: | + **Before** reporting an issue, make sure to read the documentation and search existing issues. Usage questions such as ***"How do I...?"*** belong in Discussions and will be closed. + - type: checkboxes + attributes: + label: Did you check docs and existing issues? + description: Make sure you checked all of the below before submitting an issue + options: + - label: I have read all the plugin docs + required: true + - label: I have searched the existing issues + required: true + - label: I have searched the existing issues of plugins related to this issue + required: true + - type: input + attributes: + label: "Neovim version (nvim -v)" + placeholder: "0.8.0 commit db1b0ee3b30f" + validations: + required: true + - type: input + attributes: + label: "Operating system/version" + placeholder: "MacOS 11.5" + validations: + required: true + - type: textarea + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. Please include any related errors you see in Neovim. + validations: + required: true + - type: textarea + attributes: + label: Steps To Reproduce + description: Steps to reproduce the behavior. + placeholder: | + 1. + 2. + 3. + validations: + required: true + - type: textarea + attributes: + label: Expected Behavior + description: A concise description of what you expected to happen. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..f8ce0f9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,36 @@ +name: Feature Request +description: Suggest a new feature +title: "feature: " +labels: [enhancement] +body: + - type: checkboxes + attributes: + label: Did you check the docs? + description: Make sure you read all the docs before submitting a feature request + options: + - label: I have read all the docs + required: true + - type: textarea + validations: + required: true + attributes: + label: Is your feature request related to a problem? Please describe. + description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + - type: textarea + validations: + required: true + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + - type: textarea + validations: + required: true + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered. + - type: textarea + validations: + required: false + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..b3c087d --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,61 @@ +name: Docs + +on: [push] + +jobs: + build-sources: + name: Generate docs + + permissions: + contents: write + + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + url: https://github.com/neovim/neovim/releases/download/nightly/nvim-linux64.tar.gz + steps: + - uses: actions/checkout@v3 + - run: date +%F > todays-date + - name: Restore cache for today's nightly. + uses: actions/cache@v3 + with: + path: _neovim + key: ${{ runner.os }}-${{ matrix.url }}-${{ hashFiles('todays-date') }} + + - name: Prepare + run: | + test -d _neovim || { + mkdir -p _neovim + curl -sL ${{ matrix.url }} | tar xzf - --strip-components=1 -C "${PWD}/_neovim" + } + mkdir -p ~/.local/share/nvim/site/pack/vendor/start + git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim + git clone https://github.com/tjdevries/tree-sitter-lua ~/.local/share/nvim/site/pack/vendor/start/tree-sitter-lua + ln -s $(pwd) ~/.local/share/nvim/site/pack/vendor/start + + - name: Build parser + run: | + # We have to build the parser every single time to keep up with parser changes + cd ~/.local/share/nvim/site/pack/vendor/start/tree-sitter-lua + git checkout 86f74dfb69c570f0749b241f8f5489f8f50adbea + make dist + cd - + + - name: Generating docs + run: | + export PATH="${PWD}/_neovim/bin:${PATH}" + export VIM="${PWD}/_neovim/share/nvim/runtime" + nvim --version + make docs + + - name: Push changes + uses: stefanzweifel/git-auto-commit-action@v5.0.0 + with: + file_pattern: 'doc/*.txt' + commit_message: "docs(build): auto-generate doc" + commit_user_name: "github-actions[bot]" + commit_user_email: "github-actions[bot]@users.noreply.github.com" + commit_author: "github-actions[bot] " diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..28ed6d7 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,27 @@ +name: Linting + +on: [push, pull_request] + +jobs: + luacheck: + name: Luacheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Prepare + run: | + sudo apt-get update + sudo apt-get install -y luarocks + sudo luarocks install luacheck + - name: Lint + run: make lint + stylua: + name: stylua + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: JohnnyMorganz/stylua-action@v3 + with: + version: latest + token: ${{ secrets.GITHUB_TOKEN }} + args: --color always --check lua diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ad03a15 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release + +on: + push: + tags: + - "v*" + +jobs: + luarocks-release: + name: LuaRocks release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Release + uses: nvim-neorocks/luarocks-tag-release@v5 + env: + LUAROCKS_API_KEY: ${{ secrets.LUAROCKS_API_KEY }} + with: + detailed_description: | + A simple way to kickstart your Neovim plugin development like a pro with: + - Plugin Structure + - Tests + - Docs Generation + - Linting and Formatting + - Deployment + dependencies: | + plenary.nvim + copy_directories: | + {{ neovim.plugin.dirs }} + github-release: + name: GitHub release + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Release + uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..4a8272d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,47 @@ +name: Tests + +on: [push, pull_request] + +jobs: + tests: + name: unit tests + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + rev: nightly/nvim-linux64.tar.gz + manager: sudo apt-get + packages: -y ripgrep + - os: ubuntu-latest + rev: v0.9.0/nvim-linux64.tar.gz + manager: sudo apt-get + packages: -y ripgrep + steps: + - uses: actions/checkout@v3 + - run: date +%F > todays-date + - name: Restore from todays cache + uses: actions/cache@v3 + with: + path: _neovim + key: ${{ runner.os }}-${{ matrix.rev }}-${{ hashFiles('todays-date') }} + + - name: Prepare + run: | + ${{ matrix.manager }} update + ${{ matrix.manager }} install ${{ matrix.packages }} + test -d _neovim || { + mkdir -p _neovim + curl -sL "https://github.com/neovim/neovim/releases/download/${{ matrix.rev }}" | tar xzf - --strip-components=1 -C "${PWD}/_neovim" + } + mkdir -p ~/.local/share/nvim/site/pack/vendor/start + git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim + ln -s $(pwd) ~/.local/share/nvim/site/pack/vendor/start + + - name: Run tests + run: | + export PATH="${PWD}/_neovim/bin:${PATH}" + export VIM="${PWD}/_neovim/share/nvim/runtime" + nvim --version + make test diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..b2af76a --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,37 @@ +-- .luacheckrc from Telescope +---@diagnostic disable: lowercase-global + +-- Rerun tests only if their modification time changed. +cache = true + +std = luajit +codes = true + +self = false + +-- Glorious list of warnings: https://luacheck.readthedocs.io/en/stable/warnings.html +ignore = { + -- "212", -- Unused argument, In the case of callback function, _arg_name is easier to understand than _, so this option is set to off. + -- "122", -- Indirectly setting a readonly global +} + +globals = { + -- Add here globals + -- "_", + -- "TelescopeGlobalState", + -- "_TelescopeConfigurationValues", + -- "_TelescopeConfigurationPickers", +} + +-- Global objects defined by the C code +read_globals = { + "vim", +} + +files = { + -- ["lua/telescope/builtin/init.lua"] = { + -- ignore = { + -- "631", -- allow line len > 120 + -- }, + -- }, +} diff --git a/.neoconf.json b/.neoconf.json new file mode 100644 index 0000000..a460b20 --- /dev/null +++ b/.neoconf.json @@ -0,0 +1,9 @@ +{ + "neodev": { + "library": { + "plugins": [ + "plenary.nvim" + ] + } + }, +} diff --git a/.stylua.toml b/.stylua.toml new file mode 100644 index 0000000..0fd4cb5 --- /dev/null +++ b/.stylua.toml @@ -0,0 +1,6 @@ +column_width = 120 +line_endings = "Unix" +indent_type = "Spaces" +indent_width = 2 +quote_style = "AutoPreferDouble" +no_call_parentheses = false diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..85f9ca3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 S1M0N38 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..69343b1 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +.PHONY: test lint docs init + +TESTS_DIR := tests/ +PLUGIN_DIR := lua/ + +DOC_GEN_SCRIPT := ./scripts/docs.lua +MINIMAL_INIT := ./scripts/minimal_init.vim + +test: + nvim --headless --noplugin -u ${MINIMAL_INIT} \ + -c "PlenaryBustedDirectory ${TESTS_DIR} { minimal_init = '${MINIMAL_INIT}' }" + +lint: + luacheck ${PLUGIN_DIR} + +docs: + nvim --headless --noplugin -u ${MINIMAL_INIT} \ + -c "luafile ${DOC_GEN_SCRIPT}" -c 'qa' + +init: + @nvim --headless --noplugin \ + -c "vimgrep /my_awesome_plugin/gj **/*.lua **/*.vim Makefile" \ + -c "cfdo %s/my_awesome_plugin/$(name)/ge | update" \ + -c "qa" + @find . -depth -type d -name '*my_awesome_plugin*' | \ + while read dir; do mv "$$dir" "$${dir//my_awesome_plugin/$(name)}"; done + @find . -type f -name '*my_awesome_plugin*' | \ + while read file; do mv "$$file" "$${file//my_awesome_plugin/$(name)}"; done diff --git a/README.md b/README.md new file mode 100644 index 0000000..84a991f --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +

โœจ My Awesome Plugin โœจ

+ +

+ + Tests + + + Docs + + + Release + +

+ +______________________________________________________________________ + +A simple way to kickstart your Neovim plugin development like a pro with: + +- [Plugin Structure](#-plugin-structure) +- [Tests](#-tests) +- [Docs Generation](#-docs-generation) +- [Linting and Formatting](#-linting-and-formatting) +- [Deployment](#-deployment) + +**Usage**: + +1. On the top right of this page, click on `Use this template` > `Create a new repository`. +1. Clone your new repo and `cd` into it. +1. Kickstart with + +```sh +make init name=the_name_of_your_plugin +``` + +Then, modify the `README.md`, `.github/workflows/release.yml`, and `LICENSE` files to your liking. + +## ๐Ÿ“ Plugin Structure + +- `plugin/my_awesome_plugin.lua` - *the main file, the one loaded by the plugin manager* + +- `lua/my_awesome_plugin/` + + - `init.lua` - *the main file of the plugin, the one loaded by `plugin/my_awesome_plugin.lua`* + - `math.lua` - *an example module, here we define simple math functions* + - `config.lua` - *store plugin default options and extend them with user's ones* + +- `tests/my_awesome_plugin/` + + - `my_awesome_plugin_spec.lua` - *plugin tests. Add other `*_spec.lua` files here for further testing* + +- `scripts/` + + - `docs.lua` - *Lua script to auto-generate `doc/my_awesome_plugin.txt` docs file from code annotations* + - `minimal_init.lua` - *start Neovim instances with minimal plugin configuration. Used in `Makefile`* + +- `Makefile` - *script for launching **tests**, **linting**, and docs generation* + +The other files are not important and will be mentioned in the following sections. + +## ๐Ÿงช Tests + +Tests are run using [plenary.nvim](https://github.com/nvim-lua/plenary.nvim), a Lua library for Neovim plugin development. [Here](https://github.com/nvim-lua/plenary.nvim/blob/master/TESTS_README.md) is how to write tests using plenary. + +To run the tests on your local machine for local development, you can: + +- Have the plenary plugin in your Neovim configuration and use `:PlenaryBustedDirectory tests`. +- Have the plenary repo cloned in the same directory as the my_awesome_plugin repo and use `make test`. + +When running tests on CI, plenary.nvim is cloned, and the tests are run using `make test`. + +## ๐Ÿ“š Docs Generation + +In the Vim/Neovim world, it's customary to provide documentation in the Vim style, a txt file with tags and sections that can be navigated using the `:help` command. +In Lua, we can add annotations to our code, i.e., comments starting with `---`, so that we can have the full signature of functions and modules for LSP sorcery. [Here](https://github.com/tjdevries/tree-sitter-lua/blob/master/HOWTO.md) is how to write code annotations. + +Lua code annotations can be used to generate the Vim style docs using the `docgen` module from [tree-sitter-lua](https://github.com/tjdevries/tree-sitter-lua). This is an alternative tree-sitter parser, so it's not installed by the tree-sitter plugin. To generate the docs locally, you must clone the tree-sitter-lua repo in the same directory as the my_awesome_plugin repo and use `make docs`. + +When running docs generation on CI, tree-sitter-lua is cloned, and the docs are generated using `make docs`. + +## ๐Ÿงน Linting and Formatting + +Linting highlights code that is syntactically correct but may not be the best practice and can lead to bugs or errors. +Formatting is the process of transforming code into a standardized format that makes it easier to read and understand. + +- [Luacheck](https://github.com/mpeterv/luacheck) is run by `make lint` using the configuration in the `.luacheckrc` file. +- In CI, [Stylua](https://github.com/JohnnyMorganz/StyLua) is run after linting using the configuration in the `.stylua.toml` file. + +## ๐Ÿš€ Deployment + +[Tags](https://git-scm.com/book/en/v2/Git-Basics-Tagging) are how Git marks milestones in the commit history of a repository. +Tags can be used to trigger releases, i.e., publish a specific version of the plugin on GitHub and LuaRocks. + +- A new release on GitHub is automatically created when a new tag is pushed. +- A new release on LuaRocks is automatically created when a new tag is pushed. It requires adding `LUAROCKS_API_KEY` as a secret in the repo settings. + +## ๐Ÿ‘ Acknowledgments + +Neovim is growing a nice ecosystem, but some parts of plugin development are sometimes obscure. This template is an attempt to put together best practices by copying: + +- [ellisonleao/nvim-plugin-template](https://github.com/ellisonleao/nvim-plugin-template) - *Plugin Structure* +- [nvim-telescope/telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) - *Tests, lint, docs generation* + +I highly suggest [this video tutorial](https://youtu.be/n4Lp4cV8YR0?si=lHlxQBNvbTcXPhVY) by [TJ DeVries](https://github.com/tjdevries), a walkthrough of the Neovim plugin development process. diff --git a/doc/.gitkeep b/doc/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/my_awesome_plugin.txt b/doc/my_awesome_plugin.txt new file mode 100644 index 0000000..60fba01 --- /dev/null +++ b/doc/my_awesome_plugin.txt @@ -0,0 +1,136 @@ +================================================================================ +MY_AWESOME_PLUGIN *my_awesome_plugin* + +This is a template for a plugin. It is meant to be copied and modified. The +following code is a simple example to show how to use this template and how to +take advantage of code documentation to generate plugin documentation. + +This simple example plugin provides a command to calculate the maximum or +minimum of two numbers. Moreover, the result can be rounded if specified by the +user in its configuration using the setup function. + +`:PluginName {number} {number} {max|min}` + +The plugin can be configured using the |my_awesome_plugin.setup()| function. + + +PluginNameModule *PluginNameModule* + + + Fields: ~ + {setup} (function) setup the plugin + {main} (function) calculate the max or min of two numbers and round + the result if specified by options + + +my_awesome_plugin.setup({options}) *my_awesome_plugin.setup()* + Setup the plugin + + Defaults: ~ + { + round = true + } + + Parameters: ~ + {options} (Config) config table + + +my_awesome_plugin.print({a}, {b}, {func}, {result}) *my_awesome_plugin.print()* + Print the result of the comparison + + + Parameters: ~ + {a} (number) first number + {b} (number) second number + {func} (string) "max" or "min" + {result} (number) result + + +my_awesome_plugin.main({a}, {b}, {func}) *my_awesome_plugin.main()* + Calcululate the max or min of two numbers and round the result if specified + by options + + + Parameters: ~ + {a} (number) first number + {b} (number) second number + {func} (string) "max" or "min" + + Return: ~ + number: result + + + +================================================================================ +MathModule *MathModule* + + + Fields: ~ + {max} (function) Will return the bigger number + {min} (function) Will return the smaller number + + +M.max({a}, {b}) *M.max()* + Will return the bigger number + + + Parameters: ~ + {a} (number) first number + {b} (number) second number + + Return: ~ + number: bigger number + + See: ~ + |M.min()| + + +M.min({a}, {b}) *M.min()* + Will return the smaller number + + + Parameters: ~ + {a} (number) first number + {b} (number) second number + + Return: ~ + number: smaller number + + See: ~ + |M.max()| + + +M.round({num}) *M.round()* + Will round a float number to the nearest integer + + + Parameters: ~ + {num} (number) float number + + Return: ~ + number: rounded num + + See: ~ + |math.floor()| + |math.ceil()| + + + +================================================================================ +ConfigModule *ConfigModule* + + + Fields: ~ + {defaults} (Config) default options + {options} (Config) config table extending defaults + + +Config *Config* + + + Fields: ~ + {round} (boolean) round the result after calculation + + + + vim:tw=78:ts=8:ft=help:norl: diff --git a/lua/my_awesome_plugin/config.lua b/lua/my_awesome_plugin/config.lua new file mode 100644 index 0000000..26a9528 --- /dev/null +++ b/lua/my_awesome_plugin/config.lua @@ -0,0 +1,32 @@ +---@class ConfigModule +---@field defaults Config: default options +---@field options Config: config table extending defaults +local M = {} + +M.defaults = { + round = true, +} + +---@class Config +---@field round boolean: round the result after calculation +M.options = {} + +--- We will not generate documentation for this function +--- because it has `__` as prefix. This is the one exception +--- Setup options by extending defaults with the options proveded by the user +---@param options Config: config table +M.__setup = function(options) + M.options = vim.tbl_deep_extend("force", {}, M.defaults, options or {}) +end + +---Format the defaults options table for documentation +---@return table +M.__format_keys = function() + local tbl = vim.split(vim.inspect(M.defaults), "\n") + table.insert(tbl, 1, "
")
+  table.insert(tbl, 2, "Defaults: ~")
+  table.insert(tbl, #tbl, "
") + return tbl +end + +return M diff --git a/lua/my_awesome_plugin/init.lua b/lua/my_awesome_plugin/init.lua new file mode 100644 index 0000000..0f33a08 --- /dev/null +++ b/lua/my_awesome_plugin/init.lua @@ -0,0 +1,60 @@ +---@tag my_awesome_plugin + +---@brief [[ +---This is a template for a plugin. It is meant to be copied and modified. +---The following code is a simple example to show how to use this template and how to take advantage of code +---documentation to generate plugin documentation. +--- +---This simple example plugin provides a command to calculate the maximum or minimum of two numbers. +---Moreover, the result can be rounded if specified by the user in its configuration using the setup function. +--- +---
+--- `:PluginName {number} {number} {max|min}`
+--- 
+--- +--- The plugin can be configured using the |my_awesome_plugin.setup()| function. +--- +---@brief ]] + +---@class PluginNameModule +---@field setup function: setup the plugin +---@field main function: calculate the max or min of two numbers and round the result if specified by options +local my_awesome_plugin = {} + +--- Setup the plugin +---@param options Config: config table +---@eval { ['description'] = require('my_awesome_plugin.config').__format_keys() } +my_awesome_plugin.setup = function(options) + require("my_awesome_plugin.config").__setup(options) +end + +---Print the result of the comparison +---@param a number: first number +---@param b number: second number +---@param func string: "max" or "min" +---@param result number: result +my_awesome_plugin.print = function(a, b, func, result) + local s = "The " .. func .. " of " .. a .. " and " .. b .. " is " .. result + if require("my_awesome_plugin.config").options.round then + s = s .. " (rounded)" + end + print(s) +end + +--- Calcululate the max or min of two numbers and round the result if specified by options +---@param a number: first number +---@param b number: second number +---@param func string: "max" or "min" +---@return number: result +my_awesome_plugin.main = function(a, b, func) + local options = require("my_awesome_plugin.config").options + local mymath = require("my_awesome_plugin.math") + local result = mymath[func](a, b) + if options.round then + result = mymath.round(result) + end + my_awesome_plugin.print(a, b, func, result) + return result +end + +return my_awesome_plugin diff --git a/lua/my_awesome_plugin/math.lua b/lua/my_awesome_plugin/math.lua new file mode 100644 index 0000000..fa7671d --- /dev/null +++ b/lua/my_awesome_plugin/math.lua @@ -0,0 +1,43 @@ +---@class MathModule +---@field max function: Will return the bigger number +---@field min function: Will return the smaller number +local M = {} + +--- Will return the bigger number +---@param a number: first number +---@param b number: second number +---@return number: bigger number +---@see M.min +M.max = function(a, b) + if a > b then + return a + end + return b +end + +--- Will return the smaller number +---@param a number: first number +---@param b number: second number +---@return number: smaller number +---@see M.max +M.min = function(a, b) + if a < b then + return a + end + return b +end + +--- Will round a float number to the nearest integer +---@param num number: float number +---@return number: rounded num +---@see math.floor +---@see math.ceil +M.round = function(num) + if num >= 0 then + return math.floor(num + 0.5) + else + return math.ceil(num - 0.5) + end +end + +return M diff --git a/plugin/my_awesome_plugin.lua b/plugin/my_awesome_plugin.lua new file mode 100644 index 0000000..7eeeb13 --- /dev/null +++ b/plugin/my_awesome_plugin.lua @@ -0,0 +1,8 @@ +vim.api.nvim_create_user_command("PluginName", function(args) + local a, b, func = unpack(args.fargs) + a = tonumber(a) + b = tonumber(b) + assert(a, "a must be a number") + assert(b, "b must be a number") + require("my_awesome_plugin").main(a, b, func) +end, { nargs = "+" }) diff --git a/scripts/docs.lua b/scripts/docs.lua new file mode 100644 index 0000000..786951c --- /dev/null +++ b/scripts/docs.lua @@ -0,0 +1,34 @@ +local docgen = require("docgen") + +local docs = {} + +docs.test = function() + -- Filepaths that should generate docs + local input_files = { + "./lua/my_awesome_plugin/init.lua", + "./lua/my_awesome_plugin/config.lua", + "./lua/my_awesome_plugin/math.lua", + } + + -- Maybe sort them that depends what you want and need + table.sort(input_files, function(a, b) + return #a < #b + end) + + -- Output file + local output_file = "./doc/my_awesome_plugin.txt" + local output_file_handle = io.open(output_file, "w") + assert(output_file_handle, "Could not open " .. output_file) + + for _, input_file in ipairs(input_files) do + docgen.write(input_file, output_file_handle) + end + + output_file_handle:write(" vim:tw=78:ts=8:ft=help:norl:\n") + output_file_handle:close() + vim.cmd([[checktime]]) +end + +docs.test() + +return docs diff --git a/scripts/minimal_init.vim b/scripts/minimal_init.vim new file mode 100644 index 0000000..63c29b6 --- /dev/null +++ b/scripts/minimal_init.vim @@ -0,0 +1,7 @@ +set rtp+=. +set rtp+=../plenary.nvim/ +set rtp+=../tree-sitter-lua/ + +runtime! plugin/plenary.vim +runtime! plugin/ts_lua.vim +runtime! plugin/my_awesome_plugin.lua diff --git a/tests/my_awesome_plugin/my_awesome_plugin_spec.lua b/tests/my_awesome_plugin/my_awesome_plugin_spec.lua new file mode 100644 index 0000000..7de41b4 --- /dev/null +++ b/tests/my_awesome_plugin/my_awesome_plugin_spec.lua @@ -0,0 +1,27 @@ +local plugin = require("my_awesome_plugin") + +describe("my_awesome_plugin with default", function() + it("can compute max", function() + plugin.setup({}) + assert.equals(3, plugin.main(2.5, 2.4, "max")) + assert.equals(3, plugin.main(2.4, 2.5, "max")) + end) + it("can compute min", function() + plugin.setup({}) + assert.equals(2, plugin.main(2.5, 2.4, "min")) + assert.equals(2, plugin.main(2.4, 2.5, "min")) + end) +end) + +describe("my_awesome_plugin with custom options", function() + it("can compute max", function() + plugin.setup({ round = false }) + assert.equals(2.5, plugin.main(2.5, 2.4, "max")) + assert.equals(2.5, plugin.main(2.4, 2.5, "max")) + end) + it("can compute min", function() + plugin.setup({ round = false }) + assert.equals(2.4, plugin.main(2.5, 2.4, "min")) + assert.equals(2.4, plugin.main(2.4, 2.5, "min")) + end) +end)