Add basic nvim conf, still wip
This commit is contained in:
parent
d1c2ea53a5
commit
13549985ce
21 changed files with 480 additions and 0 deletions
13
nvim/init.lua
Normal file
13
nvim/init.lua
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
local merge = vim.tbl_deep_extend
|
||||||
|
|
||||||
|
-- Load keymaps before loading any plugins
|
||||||
|
require("keymaps")
|
||||||
|
|
||||||
|
-- change and personalize native vim settings
|
||||||
|
vim.opt = require("vim_opt")
|
||||||
|
|
||||||
|
-- Initialize Lazy package manager
|
||||||
|
require("lazy_init")
|
||||||
|
|
||||||
|
-- Initialize plugins, add a plugin by creating a new file in the plugins dir
|
||||||
|
require("lazy").setup("plugs")
|
||||||
103
nvim/lua/keymaps.lua
Normal file
103
nvim/lua/keymaps.lua
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
local g = vim.g
|
||||||
|
|
||||||
|
g.mapleader = " "
|
||||||
|
g.maplocalleader = " "
|
||||||
|
|
||||||
|
local keymaps = {
|
||||||
|
n = {
|
||||||
|
-- Navigation
|
||||||
|
["<C-d>"] = {
|
||||||
|
cmd = "<S-l>zz",
|
||||||
|
},
|
||||||
|
["<C-u>"] = {
|
||||||
|
cmd = "<S-H>zz",
|
||||||
|
},
|
||||||
|
["<C-Left>"] = {
|
||||||
|
cmd = "<C-w>h",
|
||||||
|
},
|
||||||
|
["<C-Down>"] = {
|
||||||
|
cmd = "<C-w>j",
|
||||||
|
},
|
||||||
|
["<C-Up>"] = {
|
||||||
|
cmd = "<C-w>k",
|
||||||
|
},
|
||||||
|
["<C-Right>"] = {
|
||||||
|
cmd = "<C-w>l",
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Disable current highlights
|
||||||
|
["<Esc>"] = {
|
||||||
|
cmd = "<cmd> noh <CR>",
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Save
|
||||||
|
["<C-s>"] = {
|
||||||
|
cmd = "<cmd> w <CR>",
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Copies the entire file
|
||||||
|
["<C-c>"] = {
|
||||||
|
cmd = "<cmd> %y+ <CR>",
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Allow moving the cursor through wrapped lines with <Up> and <Down>
|
||||||
|
-- http://www.reddit.com/r/vim/comments/2k4cbr/problem_with_gj_and_gk/
|
||||||
|
-- empty mode is same as using <cmd> :map
|
||||||
|
-- also don't use g[j|k] when in operator pending mode, so it doesn't alter d, y or c behaviour
|
||||||
|
["<Up>"] = {
|
||||||
|
cmd = "v:count || mode(1)[0:1] == \"no\" ? \"k\" : \"gk\"",
|
||||||
|
opts = {
|
||||||
|
expr = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["<Down>"] = {
|
||||||
|
cmd = "v:count || mode(1)[0:1] == \"no\" ? \"j\" : \"gj\"",
|
||||||
|
opts = {
|
||||||
|
expr = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
i = { },
|
||||||
|
v = {
|
||||||
|
["<Up>"] = {
|
||||||
|
cmd = "v:count || mode(1)[0:1] == \"no\" ? \"k\" : \"gk\"",
|
||||||
|
opts = {
|
||||||
|
expr = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["<Down>"] = {
|
||||||
|
cmd = "v:count || mode(1)[0:1] == \"no\" ? \"j\" : \"gj\"",
|
||||||
|
opts = {
|
||||||
|
expr = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["<tab>"] = {
|
||||||
|
cmd = ">gv",
|
||||||
|
},
|
||||||
|
["<S-tab>"] = {
|
||||||
|
cmd = "<gv",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
x = {
|
||||||
|
["<Up>"] = {
|
||||||
|
cmd = "v:count || mode(1)[0:1] == \"no\" ? \"k\" : \"gk\"",
|
||||||
|
opts = {
|
||||||
|
expr = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["<Down>"] = {
|
||||||
|
cmd = "v:count || mode(1)[0:1] == \"no\" ? \"j\" : \"gj\"",
|
||||||
|
opts = {
|
||||||
|
expr = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["p"] = {
|
||||||
|
cmd = "p:let @+=@0<CR>:let @\"=@0<CR>",
|
||||||
|
opts = {
|
||||||
|
silent = true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
require("utils").add_keymaps(keymaps)
|
||||||
30
nvim/lua/language_servers/lua_ls.lua
Normal file
30
nvim/lua/language_servers/lua_ls.lua
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
return {
|
||||||
|
on_init = function(client)
|
||||||
|
local path = client.workspace_folders[1].name
|
||||||
|
if not vim.loop.fs_stat(path .. "/.luarc.json") and not vim.loop.fs_stat(path .. "/.luarc.jsonc") then
|
||||||
|
client.config.settings = vim.tbl_deep_extend("force", client.config.settings, {
|
||||||
|
Lua = {
|
||||||
|
runtime = {
|
||||||
|
-- Tell the language server which version of Lua you're using
|
||||||
|
-- (most likely LuaJIT in the case of Neovim)
|
||||||
|
version = "LuaJIT",
|
||||||
|
},
|
||||||
|
-- Make the server aware of Neovim runtime files
|
||||||
|
workspace = {
|
||||||
|
checkThirdParty = false,
|
||||||
|
library = {
|
||||||
|
vim.env.VIMRUNTIME,
|
||||||
|
-- "${3rd}/luv/library"
|
||||||
|
-- "${3rd}/busted/library",
|
||||||
|
},
|
||||||
|
-- or pull in all of 'runtimepath'. NOTE: this is a lot slower
|
||||||
|
-- library = vim.api.nvim_get_runtime_file("", true)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
client.notify("workspace/didChangeConfiguration", { settings = client.config.settings })
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
}
|
||||||
12
nvim/lua/lazy_init.lua
Normal file
12
nvim/lua/lazy_init.lua
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
local lazypath = vim.fn.stdpath("data") .. "/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)
|
||||||
5
nvim/lua/plugs/autopairs.lua
Normal file
5
nvim/lua/plugs/autopairs.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
return {
|
||||||
|
"windwp/nvim-autopairs",
|
||||||
|
event = "InsertEnter",
|
||||||
|
opts = {},
|
||||||
|
}
|
||||||
9
nvim/lua/plugs/comment.lua
Normal file
9
nvim/lua/plugs/comment.lua
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
return {
|
||||||
|
"numToStr/Comment.nvim",
|
||||||
|
opts = {
|
||||||
|
mappings = {
|
||||||
|
extra = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lazy = false,
|
||||||
|
}
|
||||||
3
nvim/lua/plugs/copilot.lua
Normal file
3
nvim/lua/plugs/copilot.lua
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
return {
|
||||||
|
"github/copilot.vim",
|
||||||
|
}
|
||||||
3
nvim/lua/plugs/devicons.lua
Normal file
3
nvim/lua/plugs/devicons.lua
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
return {
|
||||||
|
"nvim-tree/nvim-web-devicons",
|
||||||
|
}
|
||||||
31
nvim/lua/plugs/leap.lua
Normal file
31
nvim/lua/plugs/leap.lua
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
return {
|
||||||
|
"ggandor/leap.nvim",
|
||||||
|
dependencies = {
|
||||||
|
"tpope/vim-repeat",
|
||||||
|
},
|
||||||
|
config = function()
|
||||||
|
require("leap").create_default_mappings()
|
||||||
|
|
||||||
|
-- Hide the (real) cursor when leaping, and restore it afterwards.
|
||||||
|
vim.api.nvim_create_autocmd(
|
||||||
|
"User",
|
||||||
|
{
|
||||||
|
pattern = "LeapEnter",
|
||||||
|
callback = function()
|
||||||
|
vim.cmd.hi("Cursor", "blend=100")
|
||||||
|
vim.opt.guicursor:append { "a:Cursor/lCursor" }
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
vim.api.nvim_create_autocmd(
|
||||||
|
"User",
|
||||||
|
{
|
||||||
|
pattern = "LeapLeave",
|
||||||
|
callback = function()
|
||||||
|
vim.cmd.hi("Cursor", "blend=0")
|
||||||
|
vim.opt.guicursor:remove { "a:Cursor/lCursor" }
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
}
|
||||||
9
nvim/lua/plugs/lualine.lua
Normal file
9
nvim/lua/plugs/lualine.lua
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
return {
|
||||||
|
"nvim-lualine/lualine.nvim",
|
||||||
|
dependencies = {
|
||||||
|
"nvim-tree/nvim-web-devicons"
|
||||||
|
},
|
||||||
|
opts = {
|
||||||
|
theme = "tokyonight-storm",
|
||||||
|
},
|
||||||
|
}
|
||||||
35
nvim/lua/plugs/mason_lsp.lua
Normal file
35
nvim/lua/plugs/mason_lsp.lua
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
return {
|
||||||
|
"williamboman/mason.nvim",
|
||||||
|
dependencies = {
|
||||||
|
"williamboman/mason-lspconfig.nvim",
|
||||||
|
"neovim/nvim-lspconfig",
|
||||||
|
"WhoIsSethDaniel/mason-tool-installer.nvim",
|
||||||
|
"RubixDev/mason-update-all",
|
||||||
|
},
|
||||||
|
config = function()
|
||||||
|
-- Missing Rust because rust-analyzer is deprecated, and rustaceanvim is not included in mason yet, so it needs a custom setup.
|
||||||
|
-- Make sure that these are named according to lspconfig and not mason packages
|
||||||
|
local servers_names = {
|
||||||
|
"lua_ls",
|
||||||
|
}
|
||||||
|
|
||||||
|
require("mason").setup()
|
||||||
|
require("mason-lspconfig").setup()
|
||||||
|
require("mason-tool-installer").setup({
|
||||||
|
ensure_installed = servers_names,
|
||||||
|
})
|
||||||
|
require("mason-update-all").setup()
|
||||||
|
|
||||||
|
-- Iterate each server and setup
|
||||||
|
local lspconfig = require("lspconfig")
|
||||||
|
for _, server_name in ipairs(servers_names) do
|
||||||
|
local server = lspconfig[server_name]
|
||||||
|
if server then
|
||||||
|
server.setup(require("lua/language_servers/" .. server_name))
|
||||||
|
else
|
||||||
|
error("LSP server not found: " .. server_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
3
nvim/lua/plugs/plenary.lua
Normal file
3
nvim/lua/plugs/plenary.lua
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
return {
|
||||||
|
"nvim-lua/plenary.nvim",
|
||||||
|
}
|
||||||
3
nvim/lua/plugs/repeat.lua
Normal file
3
nvim/lua/plugs/repeat.lua
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
return {
|
||||||
|
"tpope/vim-repeat",
|
||||||
|
}
|
||||||
8
nvim/lua/plugs/surround.lua
Normal file
8
nvim/lua/plugs/surround.lua
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
return {
|
||||||
|
"kylechui/nvim-surround",
|
||||||
|
version = "*",
|
||||||
|
event = "VeryLazy",
|
||||||
|
config = function()
|
||||||
|
require("nvim-surround").setup({})
|
||||||
|
end,
|
||||||
|
}
|
||||||
45
nvim/lua/plugs/telescope.lua
Normal file
45
nvim/lua/plugs/telescope.lua
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
return {
|
||||||
|
"nvim-telescope/telescope.nvim",
|
||||||
|
dependencies = {
|
||||||
|
"nvim-lua/plenary.nvim",
|
||||||
|
"nvim-telescope/telescope-fzf-native.nvim",
|
||||||
|
},
|
||||||
|
config = function()
|
||||||
|
require("telescope").setup({ })
|
||||||
|
require("telescope").load_extension("fzf")
|
||||||
|
|
||||||
|
local keymaps = {
|
||||||
|
n = {
|
||||||
|
-- File search
|
||||||
|
["<leader>to"] = {
|
||||||
|
cmd = ":Telescope find_files <CR>",
|
||||||
|
},
|
||||||
|
["<leader>tf"] = {
|
||||||
|
cmd = ":Telescope current_buffer_fuzzy_find<CR>",
|
||||||
|
},
|
||||||
|
["<leader>ta"] = {
|
||||||
|
cmd = ":Telescope live_grep find_command=rg,--ignore-file,.gitignore,--exclude,*.git,--exclude,*.svn,--exclude,*.vs,--exclude,*.idea<CR>",
|
||||||
|
},
|
||||||
|
-- Git
|
||||||
|
["<leader>gc"] = {
|
||||||
|
cmd = "<cmd> Telescope git_commits <CR>",
|
||||||
|
},
|
||||||
|
["<leader>gs"] = {
|
||||||
|
cmd = "<cmd> Telescope git_status <CR>",
|
||||||
|
},
|
||||||
|
["<leader>gh"] = {
|
||||||
|
cmd = "<cmd> Telescope git_bcommits <CR>",
|
||||||
|
},
|
||||||
|
["<leader>gb"] = {
|
||||||
|
cmd = "<cmd> Telescope git_branches <CR>",
|
||||||
|
},
|
||||||
|
-- Misc
|
||||||
|
["<leader>tb"] = {
|
||||||
|
cmd = "<cmd> Telescope marks <CR>",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require("utils").add_keymaps(keymaps)
|
||||||
|
end,
|
||||||
|
}
|
||||||
4
nvim/lua/plugs/telescope_fzf.lua
Normal file
4
nvim/lua/plugs/telescope_fzf.lua
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
return {
|
||||||
|
"nvim-telescope/telescope-fzf-native.nvim",
|
||||||
|
build = "cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build",
|
||||||
|
}
|
||||||
77
nvim/lua/plugs/tokyonight.lua
Normal file
77
nvim/lua/plugs/tokyonight.lua
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
return {
|
||||||
|
"folke/tokyonight.nvim",
|
||||||
|
lazy = false,
|
||||||
|
priority = 1000,
|
||||||
|
config = function()
|
||||||
|
require("tokyonight").setup({
|
||||||
|
style = "storm",
|
||||||
|
light_style = "day",
|
||||||
|
transparent = true,
|
||||||
|
terminal_colors = true,
|
||||||
|
styles = {
|
||||||
|
comments = {},
|
||||||
|
keywords = {},
|
||||||
|
functions = {},
|
||||||
|
variables = {},
|
||||||
|
sidebars = "dark",
|
||||||
|
floats = "dark"
|
||||||
|
},
|
||||||
|
sidebars = { "qf", "help" },
|
||||||
|
day_brightness = 0.3,
|
||||||
|
hide_inactive_statusline = false,
|
||||||
|
dim_inactive = false,
|
||||||
|
lualine_bold = true,
|
||||||
|
|
||||||
|
--- You can override specific color groups to use other groups or a hex color
|
||||||
|
--- function will be called with a ColorScheme table
|
||||||
|
---@param colors ColorScheme
|
||||||
|
on_colors = function(colors) end,
|
||||||
|
|
||||||
|
--- You can override specific highlights to use other groups or a hex color
|
||||||
|
--- function will be called with a Highlights and ColorScheme table
|
||||||
|
---@param highlights Highlights
|
||||||
|
---@param colors ColorScheme
|
||||||
|
on_highlights = function(highlights, colors)
|
||||||
|
local prompt = "#2d3149"
|
||||||
|
highlights.TelescopeNormal = {
|
||||||
|
bg = colors.bg_dark,
|
||||||
|
fg = colors.fg_dark,
|
||||||
|
}
|
||||||
|
highlights.TelescopeBorder = {
|
||||||
|
bg = colors.bg_dark,
|
||||||
|
fg = colors.bg_dark,
|
||||||
|
}
|
||||||
|
highlights.TelescopePromptNormal = {
|
||||||
|
bg = prompt,
|
||||||
|
}
|
||||||
|
highlights.TelescopePromptBorder = {
|
||||||
|
bg = prompt,
|
||||||
|
fg = prompt,
|
||||||
|
}
|
||||||
|
highlights.TelescopePromptTitle = {
|
||||||
|
bg = prompt,
|
||||||
|
fg = prompt,
|
||||||
|
}
|
||||||
|
highlights.TelescopePreviewTitle = {
|
||||||
|
bg = colors.bg_dark,
|
||||||
|
fg = colors.bg_dark,
|
||||||
|
}
|
||||||
|
highlights.TelescopeResultsTitle = {
|
||||||
|
bg = colors.bg_dark,
|
||||||
|
fg = colors.bg_dark,
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.cmd[[colorscheme tokyonight-storm]]
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Usecase example for other plugins when adding colorscheme support
|
||||||
|
--[[
|
||||||
|
local colors = require("tokyonight.colors").setup() -- pass in any of the config options as explained above
|
||||||
|
local util = require("tokyonight.util")
|
||||||
|
|
||||||
|
aplugin.background = colors.bg_dark
|
||||||
|
aplugin.my_error = util.lighten(colors.red1, 0.3) -- number between 0 and 1. 0 results in white, 1 results in red1
|
||||||
|
]]--
|
||||||
18
nvim/lua/plugs/treesitter.lua
Normal file
18
nvim/lua/plugs/treesitter.lua
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
return {
|
||||||
|
"nvim-treesitter/nvim-treesitter",
|
||||||
|
opts = {
|
||||||
|
ensure_installed = {
|
||||||
|
"vim",
|
||||||
|
"vimdoc",
|
||||||
|
"lua"
|
||||||
|
},
|
||||||
|
sync_install = false,
|
||||||
|
-- This can be updated to a list of languages instead of defaulting to true
|
||||||
|
highlight = { enable = true },
|
||||||
|
indent = {enable = true },
|
||||||
|
},
|
||||||
|
build = ":TSUpdate",
|
||||||
|
dependencies = {
|
||||||
|
"nvim-treesitter/nvim-treesitter-context"
|
||||||
|
}
|
||||||
|
}
|
||||||
3
nvim/lua/plugs/treesitter_context.lua
Normal file
3
nvim/lua/plugs/treesitter_context.lua
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
return {
|
||||||
|
"nvim-treesitter/nvim-treesitter-context"
|
||||||
|
}
|
||||||
11
nvim/lua/utils.lua
Normal file
11
nvim/lua/utils.lua
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
function M.add_keymaps(maps)
|
||||||
|
for mode, entries in pairs(maps) do
|
||||||
|
for code, info in pairs(entries) do
|
||||||
|
vim.keymap.set(mode, code, info.cmd, info.opts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
55
nvim/lua/vim_opt.lua
Normal file
55
nvim/lua/vim_opt.lua
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
local opt = vim.opt
|
||||||
|
|
||||||
|
-- Disable tabs, will use telescope and harpoon instead
|
||||||
|
opt.showtabline = 0
|
||||||
|
|
||||||
|
-- Make Vim use the system clipboard
|
||||||
|
opt.clipboard = "unnamedplus"
|
||||||
|
|
||||||
|
-- Highlight the currently selected row
|
||||||
|
opt.cursorline = true
|
||||||
|
opt.cursorlineopt = "both"
|
||||||
|
|
||||||
|
-- Indenting
|
||||||
|
opt.expandtab = true
|
||||||
|
opt.smartindent = true
|
||||||
|
opt.breakindent = true
|
||||||
|
opt.shiftwidth = 4
|
||||||
|
opt.tabstop = 4
|
||||||
|
opt.softtabstop = 4
|
||||||
|
|
||||||
|
-- Disable home screen
|
||||||
|
opt.shortmess:append("sI")
|
||||||
|
|
||||||
|
-- Signcolumn
|
||||||
|
opt.signcolumn = "yes:1" -- Adds a spacing to the left which can contain gutter icons
|
||||||
|
opt.fillchars = { eob = " " } -- Remove the fill character for empty lines which defaults to: "~"
|
||||||
|
|
||||||
|
-- Search
|
||||||
|
opt.ignorecase = true
|
||||||
|
opt.smartcase = true
|
||||||
|
opt.incsearch = true
|
||||||
|
|
||||||
|
-- Disable mouse support
|
||||||
|
opt.mouse = ""
|
||||||
|
|
||||||
|
-- Numbers
|
||||||
|
opt.number = true
|
||||||
|
opt.relativenumber = true
|
||||||
|
opt.numberwidth = 4
|
||||||
|
|
||||||
|
-- Decrease update time
|
||||||
|
opt.updatetime = 250
|
||||||
|
opt.timeoutlen = 300
|
||||||
|
|
||||||
|
-- Richer colors in terminal, not all terminals support this
|
||||||
|
opt.termguicolors = true
|
||||||
|
|
||||||
|
-- Disable swapfile, 99/100 times it just gets in the way
|
||||||
|
opt.swapfile = false
|
||||||
|
|
||||||
|
-- Buffers
|
||||||
|
opt.splitright = true
|
||||||
|
opt.splitbelow = true
|
||||||
|
|
||||||
|
return opt
|
||||||
Loading…
Add table
Add a link
Reference in a new issue