Merge pull request #8 from barrettruth/chore/add-project-configs
chore: add project configs
This commit is contained in:
commit
838541539e
24 changed files with 516 additions and 130 deletions
9
.editorconfig
Normal file
9
.editorconfig
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[*.lua]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
77
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
77
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
name: Bug Report
|
||||||
|
description: Report a bug
|
||||||
|
title: "bug: "
|
||||||
|
labels: [bug]
|
||||||
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Prerequisites
|
||||||
|
options:
|
||||||
|
- label: I have searched [existing
|
||||||
|
issues](https://github.com/barrettruth/http-codes.nvim/issues)
|
||||||
|
required: true
|
||||||
|
- label: I have updated to the latest version
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: "Neovim version"
|
||||||
|
description: "Output of `nvim --version`"
|
||||||
|
render: text
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: "Operating system"
|
||||||
|
placeholder: "e.g. Arch Linux, macOS 15, Ubuntu 24.04"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: What happened? What did you expect?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: Minimal steps to trigger the bug
|
||||||
|
value: |
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: "Health check"
|
||||||
|
description: "Output of `:checkhealth http-codes`"
|
||||||
|
render: text
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Minimal reproduction
|
||||||
|
description: |
|
||||||
|
Save the script below as `repro.lua`, edit if needed, and run:
|
||||||
|
```
|
||||||
|
nvim -u repro.lua
|
||||||
|
```
|
||||||
|
Confirm the bug reproduces with this config before submitting.
|
||||||
|
render: lua
|
||||||
|
value: |
|
||||||
|
vim.env.LAZY_STDPATH = '.repro'
|
||||||
|
load(vim.fn.system('curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua'))()
|
||||||
|
require('lazy.nvim').setup({
|
||||||
|
spec = {
|
||||||
|
{
|
||||||
|
'barrett-ruth/http-codes.nvim',
|
||||||
|
opts = {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
5
.github/ISSUE_TEMPLATE/config.yaml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yaml
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Questions
|
||||||
|
url: https://github.com/barrettruth/http-codes.nvim/discussions
|
||||||
|
about: Ask questions and discuss ideas
|
||||||
29
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
29
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
name: Feature Request
|
||||||
|
description: Suggest a feature
|
||||||
|
title: "feat: "
|
||||||
|
labels: [enhancement]
|
||||||
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Prerequisites
|
||||||
|
options:
|
||||||
|
- label: I have searched [existing
|
||||||
|
issues](https://github.com/barrettruth/http-codes.nvim/issues)
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Problem
|
||||||
|
description: What problem does this solve?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Proposed solution
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Alternatives considered
|
||||||
61
.github/workflows/ci.yaml
vendored
Normal file
61
.github/workflows/ci.yaml
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
name: ci
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
changes:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
lua: ${{ steps.changes.outputs.lua }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dorny/paths-filter@v3
|
||||||
|
id: changes
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
lua:
|
||||||
|
- 'lua/**'
|
||||||
|
- 'plugin/**'
|
||||||
|
- '*.lua'
|
||||||
|
- '.luarc.json'
|
||||||
|
- 'stylua.toml'
|
||||||
|
- 'selene.toml'
|
||||||
|
|
||||||
|
lua-format:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: changes
|
||||||
|
if: ${{ needs.changes.outputs.lua == 'true' }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: JohnnyMorganz/stylua-action@v4
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
version: 2.1.0
|
||||||
|
args: --check .
|
||||||
|
|
||||||
|
lua-lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: changes
|
||||||
|
if: ${{ needs.changes.outputs.lua == 'true' }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: NTBBloodbath/selene-action@v1.0.0
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
args: --display-style quiet .
|
||||||
|
|
||||||
|
lua-typecheck:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: changes
|
||||||
|
if: ${{ needs.changes.outputs.lua == 'true' }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: mrcjkb/lua-typecheck-action@v0
|
||||||
|
with:
|
||||||
|
checklevel: Warning
|
||||||
|
directories: lua
|
||||||
|
configpath: .luarc.json
|
||||||
21
.github/workflows/luarocks.yaml
vendored
Normal file
21
.github/workflows/luarocks.yaml
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
name: luarocks
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
uses: ./.github/workflows/ci.yaml
|
||||||
|
|
||||||
|
publish:
|
||||||
|
needs: ci
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: nvim-neorocks/luarocks-tag-release@v7
|
||||||
|
env:
|
||||||
|
LUAROCKS_API_KEY: ${{ secrets.LUAROCKS_API_KEY }}
|
||||||
89
.github/workflows/quality.yaml
vendored
Normal file
89
.github/workflows/quality.yaml
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
name: quality
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
changes:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
lua: ${{ steps.changes.outputs.lua }}
|
||||||
|
markdown: ${{ steps.changes.outputs.markdown }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dorny/paths-filter@v3
|
||||||
|
id: changes
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
lua:
|
||||||
|
- 'lua/**'
|
||||||
|
- 'plugin/**'
|
||||||
|
- '*.lua'
|
||||||
|
- '.luarc.json'
|
||||||
|
- '*.toml'
|
||||||
|
markdown:
|
||||||
|
- '*.md'
|
||||||
|
- 'doc/**/*.md'
|
||||||
|
|
||||||
|
lua-format:
|
||||||
|
name: Lua Format Check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: changes
|
||||||
|
if: ${{ needs.changes.outputs.lua == 'true' }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: JohnnyMorganz/stylua-action@v4
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
version: 2.1.0
|
||||||
|
args: --check .
|
||||||
|
|
||||||
|
lua-lint:
|
||||||
|
name: Lua Lint Check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: changes
|
||||||
|
if: ${{ needs.changes.outputs.lua == 'true' }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Lint with Selene
|
||||||
|
uses: NTBBloodbath/selene-action@v1.0.0
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
args: --display-style quiet .
|
||||||
|
|
||||||
|
lua-typecheck:
|
||||||
|
name: Lua Type Check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: changes
|
||||||
|
if: ${{ needs.changes.outputs.lua == 'true' }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Run Lua LS Type Check
|
||||||
|
uses: mrcjkb/lua-typecheck-action@v0
|
||||||
|
with:
|
||||||
|
checklevel: Warning
|
||||||
|
directories: lua
|
||||||
|
configpath: .luarc.json
|
||||||
|
|
||||||
|
markdown-format:
|
||||||
|
name: Markdown Format Check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: changes
|
||||||
|
if: ${{ needs.changes.outputs.markdown == 'true' }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
with:
|
||||||
|
version: 8
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "20"
|
||||||
|
- name: Install prettier
|
||||||
|
run: pnpm add -g prettier@3.1.0
|
||||||
|
- name: Check markdown formatting with prettier
|
||||||
|
run: prettier --check .
|
||||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
doc/tags
|
||||||
|
.*cache*
|
||||||
|
CLAUDE.md
|
||||||
|
.claude/
|
||||||
8
.luarc.json
Normal file
8
.luarc.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"runtime.version": "Lua 5.1",
|
||||||
|
"runtime.path": ["lua/?.lua", "lua/?/init.lua"],
|
||||||
|
"diagnostics.globals": ["vim", "jit"],
|
||||||
|
"workspace.library": ["$VIMRUNTIME/lua", "${3rd}/luv/library"],
|
||||||
|
"workspace.checkThirdParty": false,
|
||||||
|
"completion.callSnippet": "Replace"
|
||||||
|
}
|
||||||
17
.pre-commit-config.yaml
Normal file
17
.pre-commit-config.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
minimum_pre_commit_version: "3.5.0"
|
||||||
|
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/JohnnyMorganz/StyLua
|
||||||
|
rev: v2.3.1
|
||||||
|
hooks:
|
||||||
|
- id: stylua-github
|
||||||
|
name: stylua (Lua formatter)
|
||||||
|
files: \.lua$
|
||||||
|
pass_filenames: true
|
||||||
|
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||||
|
rev: v4.0.0-alpha.8
|
||||||
|
hooks:
|
||||||
|
- id: prettier
|
||||||
|
name: prettier
|
||||||
|
files: \.(md|toml|ya?ml|sh)$
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
collapse_simple_statement = "Always"
|
|
||||||
quote_style = "AutoPreferSingle"
|
|
||||||
call_parentheses = "None"
|
|
||||||
indent_type = "Spaces"
|
|
||||||
column_width = 80
|
|
||||||
|
|
@ -13,6 +13,7 @@ luarocks install http-codes.nvim
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
One of:
|
One of:
|
||||||
|
|
||||||
- [fzf-lua](https://github.com/ibhagwan/fzf-lua)
|
- [fzf-lua](https://github.com/ibhagwan/fzf-lua)
|
||||||
- [snacks.nvim](https://github.com/folke/snacks.nvim)
|
- [snacks.nvim](https://github.com/folke/snacks.nvim)
|
||||||
- [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
|
- [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
|
||||||
12
http-codes.nvim-scm-1.rockspec
Normal file
12
http-codes.nvim-scm-1.rockspec
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
rockspec_format = '3.0'
|
||||||
|
package = 'http-codes.nvim'
|
||||||
|
version = 'scm-1'
|
||||||
|
|
||||||
|
source = { url = 'git://github.com/barrettruth/http-codes.nvim' }
|
||||||
|
build = { type = 'builtin' }
|
||||||
|
|
||||||
|
test_dependencies = {
|
||||||
|
'lua >= 5.1',
|
||||||
|
'nlua',
|
||||||
|
'busted >= 2.1.1',
|
||||||
|
}
|
||||||
|
|
@ -32,7 +32,10 @@ local function init()
|
||||||
end
|
end
|
||||||
|
|
||||||
if not config.use then
|
if not config.use then
|
||||||
vim.notify_once('http-codes.nvim: install fzf-lua, snacks.nvim, or telescope.nvim', vim.log.levels.ERROR)
|
vim.notify_once(
|
||||||
|
'http-codes.nvim: install fzf-lua, snacks.nvim, or telescope.nvim',
|
||||||
|
vim.log.levels.ERROR
|
||||||
|
)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -70,7 +73,13 @@ M.http_codes = M.pick
|
||||||
|
|
||||||
---@deprecated Use `vim.g.http_codes` instead
|
---@deprecated Use `vim.g.http_codes` instead
|
||||||
function M.setup(user_config)
|
function M.setup(user_config)
|
||||||
vim.deprecate('require("http-codes").setup()', 'vim.g.http_codes', 'v0.1.0', 'http-codes.nvim', false)
|
vim.deprecate(
|
||||||
|
'require("http-codes").setup()',
|
||||||
|
'vim.g.http_codes',
|
||||||
|
'v0.1.0',
|
||||||
|
'http-codes.nvim',
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
if user_config then
|
if user_config then
|
||||||
vim.g.http_codes = vim.tbl_deep_extend('force', vim.g.http_codes or {}, user_config)
|
vim.g.http_codes = vim.tbl_deep_extend('force', vim.g.http_codes or {}, user_config)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
local codes = require 'http-codes.codes'
|
local codes = require('http-codes.codes')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pick = function(open_url)
|
pick = function(open_url)
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,20 @@ local OS_TO_OPEN_URL = {
|
||||||
}
|
}
|
||||||
|
|
||||||
local function get_os()
|
local function get_os()
|
||||||
if jit then return jit.os end
|
if jit then
|
||||||
|
return jit.os
|
||||||
|
end
|
||||||
|
|
||||||
local fh, _ = assert(io.popen('uname -o 2>/dev/null', 'r'))
|
local fh, _ = assert(io.popen('uname -o 2>/dev/null', 'r'))
|
||||||
if fh then return fh:read() end
|
if fh then
|
||||||
|
return fh:read()
|
||||||
|
end
|
||||||
|
|
||||||
return fh and fh:read() or 'Windows'
|
return fh and fh:read() or 'Windows'
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
get_open_url = function() return OS_TO_OPEN_URL[get_os()] or 'xdg-open %s' end,
|
get_open_url = function()
|
||||||
|
return OS_TO_OPEN_URL[get_os()] or 'xdg-open %s'
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
local codes = require 'http-codes.codes'
|
local codes = require('http-codes.codes')
|
||||||
local cached_items = nil
|
local cached_items = nil
|
||||||
|
|
||||||
local function codes_to_snack_items(codes)
|
local function codes_to_snack_items(codes_map)
|
||||||
if cached_items then return cached_items end
|
if cached_items then
|
||||||
|
return cached_items
|
||||||
|
end
|
||||||
|
|
||||||
local items = {}
|
local items = {}
|
||||||
|
|
||||||
local idx = 1
|
local idx = 1
|
||||||
for status, _ in pairs(codes) do
|
for status, _ in pairs(codes_map) do
|
||||||
table.insert(items, { idx = idx, text = status })
|
table.insert(items, { idx = idx, text = status })
|
||||||
idx = idx + 1
|
idx = idx + 1
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
return {
|
return {
|
||||||
setup = function() require('telescope').load_extension 'http' end,
|
setup = function()
|
||||||
|
require('telescope').load_extension('http')
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
local list = require 'telescope._extensions.http.list'
|
local list = require('telescope._extensions.http.list')
|
||||||
|
|
||||||
return require('telescope').register_extension {
|
return require('telescope').register_extension({
|
||||||
exports = { list = list },
|
exports = { list = list },
|
||||||
}
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
local actions = require 'telescope.actions'
|
local actions = require('telescope.actions')
|
||||||
local finders = require 'telescope.finders'
|
local finders = require('telescope.finders')
|
||||||
local pickers = require 'telescope.pickers'
|
local pickers = require('telescope.pickers')
|
||||||
local sorters = require 'telescope.sorters'
|
local sorters = require('telescope.sorters')
|
||||||
local state = require 'telescope.actions.state'
|
local state = require('telescope.actions.state')
|
||||||
|
|
||||||
local codes = require 'http-codes.codes'
|
local codes = require('http-codes.codes')
|
||||||
|
|
||||||
return function(open_url)
|
return function(open_url)
|
||||||
pickers
|
pickers
|
||||||
.new(nil, {
|
.new(nil, {
|
||||||
prompt_title = 'HTTP Codes',
|
prompt_title = 'HTTP Codes',
|
||||||
finder = finders.new_table {
|
finder = finders.new_table({
|
||||||
results = vim.tbl_keys(codes),
|
results = vim.tbl_keys(codes),
|
||||||
},
|
}),
|
||||||
sorter = sorters.get_generic_fuzzy_sorter(),
|
sorter = sorters.get_generic_fuzzy_sorter(),
|
||||||
attach_mappings = function(prompt_bufnr, _)
|
attach_mappings = function(prompt_bufnr, _)
|
||||||
actions.select_default:replace(function()
|
actions.select_default:replace(function()
|
||||||
|
|
|
||||||
1
selene.toml
Normal file
1
selene.toml
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
std = 'vim'
|
||||||
8
stylua.toml
Normal file
8
stylua.toml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
column_width = 100
|
||||||
|
line_endings = "Unix"
|
||||||
|
indent_type = "Spaces"
|
||||||
|
indent_width = 2
|
||||||
|
quote_style = "AutoPreferSingle"
|
||||||
|
call_parentheses = "Always"
|
||||||
|
[sort_requires]
|
||||||
|
enabled = true
|
||||||
30
vim.toml
Normal file
30
vim.toml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
[selene]
|
||||||
|
base = "lua51"
|
||||||
|
name = "vim"
|
||||||
|
|
||||||
|
[vim]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[jit]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[assert]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[describe]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[it]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[before_each]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[after_each]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[spy]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[stub]
|
||||||
|
any = true
|
||||||
Loading…
Add table
Add a link
Reference in a new issue