huggingface / huggingface/llm.nvim

[Feat]: Improve DX

Open
#96 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Lua
Stars
1.2k
Forks
58
Avg merge
30m
Merged PRs (30d)
1

Description

# Motivation

When I was working on the files, there were no rules for the linters nor lsp, `lua_ls` and (in my case) `selene` will complain about unused variables, parameters, shadowing, etc.

## Proposal

- **Linter**: I will personally go for [selene](https://github.com/Kampfkarren/selene) (a more updated and better approach than [luacheck](https://github.com/mpeterv/luacheck))

## Configuration example

### Linters

- Selene:

Expand to see configuration

```toml
# selene.toml or .selene.toml
std="neovim" # looks for a `neovim.yml` file to use as configuration

[rules]
global_usage = "warn"
deprecated = "warn" # If changed to `allow` it will rely in `lua_ls` diagnostics alone
multiple_statements = "warn"
incorrect_standard_library_use = "allow" # This is for cases like `string.format`, `package.config`, etc.
mixed_table = "allow"
unused_variable = "warn"
undefined_variable = "warn"
```

```yml
# neovim.yml
---
base: lua51 # to use lua5.1 what Neovim uses

globals:
jit:
any: true
vim:
any: true
assert:
args:
- type: bool
- type: string
required: false
after_each:
args:
- type: function
before_each:
args:
- type: function
describe:
args:
- type: string
- type: function
it:
args:
- type: string
- type: function
```

---

- Luacheck: (pulled from [plenay.nvim](https://github.com/nvim-lua/plenary.nvim))

Expand to see configuration

```lua
-- .luacheckrc
-- 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 = {
"_",
"_PlenaryLeafTable",
"_PlenaryBustedOldAssert",
"_AssociatedBufs",
}

-- Global objects defined by the C code
read_globals = {
"vim",
}

exclude_files = {
"lua/plenary/profile/lua_profiler.lua",
"lua/plenary/profile/memory_profiler.lua",
"lua/plenary/async_lib/*.lua",
}

files = {
["lua/plenary/busted.lua"] = {
globals = {
"describe",
"it",
"pending",
"before_each",
"after_each",
"clear",
"assert",
"print",
},
},
["lua/plenary/async/init.lua"] = {
globals = {
"a",
},
},
["lua/plenary/async/tests.lua"] = {
globals = {
"describe",
"it",
"pending",
"before_each",
"after_each",
},
},
}
```

### Formatter

We can also add a `Makefile` to use `make lint` and `make format`.

```Makefile
lint:
@printf "\nRunning linter\n"
@selene --display-style quiet --config ./selene.toml lua/llm
# @luacheck lua/llm
@printf "\Running formatter check\n"
@stylua --color always -f ./.stylua.toml --check .

format:
@printf "\nFixing all fixable formatting problems\n"
@stylua --color always -f ./.stylua.toml .
```

Also the native support for `.editorconfig` in Neovim to ensure code style not only in lua files.

---

## Integrating linters and formatters in worflows

- Selene and stylua:

```yml
name: lint

on:
pull_request:
branches:
- main
paths:
- "lua/**"
- "tests/**"

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Run selene
uses: NTBBloodbath/selene-action@v1.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --display-style quiet lua/llm

style-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Lint with stylua
uses: JohnnyMorganz/stylua-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: latest
args: --color always --check .
```

> [!NOTE]
>
> Both `stylua` and `selene` are installable from [cargo](https://crates.io/).
>
> We could use a cargo install package and then run `make lint` if
> using the `Makefile` approach.

- Luacheck and stylua:

```yml
name: lint

on:
pull_request:
branches:
- main
paths:
- "lua/**"
- "tests/**"

jobs:
stylua:
name: stylua
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: JohnnyMorganz/stylua-action@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: latest
# CLI arguments
args: --color always --check .

luacheck:
name: Luacheck
runs-on: ubuntu-22.04
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
```

---

## Contributing rules, standards and code of conduct

Adding a `CONTRIBUTING.md` and a `CODE_OF_CONDUCT.md` for easy to follow instructions on how to change the repo.

In `CONTRIBUTING.md` we could specify and tell the linters and formatters, how to structure the code, if following [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) standards or not and some how to `fork` the repo just in case. We could also add a `minimal.lua` configuration to test errors for bugs.

minimal.lua config example

```bash
nvim -nu minimal.lua
```

```lua
vim.cmd([[set runtimepath=$VIMRUNTIME]])
vim.cmd([[set packpath=/tmp/nvim/lazy/]])

local lazypath = "/tmp/nvim/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end

vim.opt.rtp:prepend(lazypath)

require("lazy").setup({
{
"huggingface/llm.nvim",
config = function()
require("llm").setup({
-- cf Setup
}),
end,
lazy = false,
enabled = true,
},
})
```

Some example of this [here](https://github.com/AlejandroSuero/freeze-code.nvim/blob/main/CONTRIBUTING.md).

## Issue and PR templating

Establish issues templates at leats for differentiating from **BUG** or **FEATURE REQUEST**, and adding `bug` or `enhancement` labels for easy to spot on the issues page.

> [!NOTE]
>
> With the new Github templating form system, we could create a form like issue for bugs, like `ISSUE_TEMPLATE/bug_report.yml`.
> Making sure the issuer check requirements like if it has used the `minimal.lua` configuration, and point them to it.
>
> We can make `required` checks and areas so it won't submit unless checked or filled. Like
an example of the configuration used or the Neovim version running, etc..

Some example of this [here](https://github.com/neovim/neovim/tree/master/.github/ISSUE_TEMPLATE).

Adding a PR template to follow a changes made format on how it was being tested or not tested, which issue or features closes or fixes with `Fixes #`.

Some example of this [here](https://github.com/AlejandroSuero/freeze-code.nvim/blob/main/.github/PULL_REQUEST_TEMPLATE.md).

## Workflows actions

> [!NOTE]
>
> Some of these notes are unnecessary per se, but they add some flavour to the project 😁.

### Labelers

We could some actions to improve labeling depending on the files touched in the PRs with [actions/labeler](https://github.com/actions/labeler) in combination with [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request)

Another action that I find very useful is [eps1lon/actions-label-merge-conflict](https://github.com/eps1lon/actions-label-merge-conflict), labels the PR with a label (`conflicted` for example) and sends a message to the PR telling the people on the PR that they need to solve conflicts with their PR.

### Commits

For linting commits I find more useful and less annoying to use [commitlint](https://commitlint.js.org/) in CI than in `hooks`, allowing the person committing a change to not have to wait locally to commit changes. This action is as simple as:

```bash
# Using this inside an action with the `run` key
npm install --save-dev @commitlint/{cli,config-conventional}
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
npx commitlint --from HEAD~1 --to HEAD --verbose
```

> If we use [conventional commits]() in the repo of course.

> [!NOTE]
>
>For formatting an linting code refer to **Integrating linters and formatters** section above.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.