supermaven-inc / supermaven-nvim

The official Neovim plugin for Supermaven
https://supermaven.com/
MIT License
279 stars 16 forks source link

[Feat] Improving developer experience #24

Open AlejandroSuero opened 1 month ago

AlejandroSuero commented 1 month ago

Motivation

When I was working on the files, some have trailing whitespaces, and there is no formatting or linting rules. So every time I format the file I have to undo it so it doesn't change the whole file.

Proposal

Configuration example

Linters

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 ```

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

Expand to see configuration ```toml # stylua.toml or .stylua.toml column_width = 120 line_endings = "Unix" indent_type = "Spaces" indent_width = 2 quote_style = "AutoPreferDouble" call_parentheses = "Always" collapse_simple_statement = "Never" [sort_requires] enabled = true ```

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

lint:
   @printf "\nRunning linter\n"
   @selene --display-style quiet --config ./selene.toml lua/supermave-nvim
   # @luacheck lua/supermaven-nvim
   @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 .

Integrating linters and formatters in worflows

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/freeze-code

  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.

We could use a cargo install package and then run make lint if using the Makefile approach.

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: sudo 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 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({ { "supermaven-inc/supermaven-nvim", config = function() require("supermaven-nvim").setup() end, lazy = false, enabled = true, }, }) ```

Some example of this here.

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.

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 #<issue number>.

Some example of this here.

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 in combination with amannn/action-semantic-pull-request, for example, if the title of the PR starts with fix and touches a file from lua/supermaven-nvim/binary, it will add a label like bugfix-binary.

Another action that I find very useful is 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.

Linters

For linting commits I find more useful and less annoying to use [commitlint]() 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:

# 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.