Refactor LSP and add notify
This commit is contained in:
@@ -14,14 +14,18 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local module_name = "base"
|
||||||
|
|
||||||
|
local utils = require("utils")
|
||||||
|
|
||||||
local files = { "globals", "options", "autocommands", "mappings", }
|
local files = { "globals", "options", "autocommands", "mappings", }
|
||||||
|
|
||||||
for _, file in ipairs(files) do
|
for _, file in ipairs(files) do
|
||||||
local pkg = "core." .. file
|
local pkg = "core." .. file
|
||||||
local ok, err = pcall(require, pkg)
|
local ok, err = pcall(require, pkg)
|
||||||
if not ok then
|
if not ok then
|
||||||
print("Error while loading package " .. pkg)
|
utils.err("Error while loading package " .. pkg, module_name)
|
||||||
print(err)
|
utils.err(err, module_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -31,15 +35,15 @@ if vim.g.vscode then
|
|||||||
else
|
else
|
||||||
local ok, err = pcall(require, "bootstrap")
|
local ok, err = pcall(require, "bootstrap")
|
||||||
if not ok then
|
if not ok then
|
||||||
print("Error during bootstrap")
|
utils.err("Error during bootstrap", module_name)
|
||||||
print(err:gsub("\t", " "))
|
utils.err(err:gsub("\t", " "), module_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
ok, err = pcall(require, "plugins")
|
ok, err = pcall(require, "plugins")
|
||||||
if not ok then
|
if not ok then
|
||||||
print("Error while loading plugins")
|
utils.err("Error while loading plugins", module_name)
|
||||||
print(err:gsub("\t", " "))
|
utils.err(err:gsub("\t", " "), module_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
vim.notify = require("notify")
|
||||||
|
require("telescope").load_extension("notify")
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
--[[
|
|
||||||
Copyright 2023 Oscar Wallberg
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
]]
|
|
||||||
|
|
||||||
return {
|
|
||||||
cmd = { "golangci-lint-langserver", },
|
|
||||||
init_options = {
|
|
||||||
command = { "golangci-lint", "run", "--out-format", "json", },
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
--[[
|
|
||||||
Copyright 2023 Oscar Wallberg
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
]]
|
|
||||||
|
|
||||||
return {
|
|
||||||
cmd = { "gopls", "serve", },
|
|
||||||
-- https://github.com/golang/tools/blob/master/gopls/doc/settings.md
|
|
||||||
settings = {
|
|
||||||
gopls = {
|
|
||||||
gofumpt = true,
|
|
||||||
codelenses = {
|
|
||||||
gc_details = true,
|
|
||||||
generate = true,
|
|
||||||
regenerate_cgo = true,
|
|
||||||
run_vulncheck_exp = true,
|
|
||||||
tidy = true,
|
|
||||||
upgrade_dependency = true,
|
|
||||||
vendor = true,
|
|
||||||
},
|
|
||||||
usePlaceholders = true,
|
|
||||||
analyses = {
|
|
||||||
asmdecl = true,
|
|
||||||
assign = true,
|
|
||||||
atomic = true,
|
|
||||||
atomicalign = true,
|
|
||||||
bools = true,
|
|
||||||
buildtag = true,
|
|
||||||
cgocall = true,
|
|
||||||
composites = true,
|
|
||||||
copylocks = true,
|
|
||||||
deepequalerrors = true,
|
|
||||||
embed = true,
|
|
||||||
errorsas = true,
|
|
||||||
fieldalignment = true,
|
|
||||||
httpresponse = true,
|
|
||||||
ifaceassert = true,
|
|
||||||
infertypeargs = true,
|
|
||||||
loopclosure = true,
|
|
||||||
lostcancel = true,
|
|
||||||
nilfunc = true,
|
|
||||||
nilness = true,
|
|
||||||
printf = true,
|
|
||||||
shadow = true,
|
|
||||||
shift = true,
|
|
||||||
simplifycompositelit = true,
|
|
||||||
simplifyrange = true,
|
|
||||||
simplifyslice = true,
|
|
||||||
sortslice = true,
|
|
||||||
stdmethods = true,
|
|
||||||
stringintconv = true,
|
|
||||||
structtag = true,
|
|
||||||
testinggoroutine = true,
|
|
||||||
tests = true,
|
|
||||||
timeformat = true,
|
|
||||||
unmarshal = true,
|
|
||||||
unreachable = true,
|
|
||||||
unsafeptr = true,
|
|
||||||
unusedparams = true,
|
|
||||||
unusedresult = true,
|
|
||||||
unusedwrite = true,
|
|
||||||
useany = true,
|
|
||||||
fillreturns = true,
|
|
||||||
nonewvars = true,
|
|
||||||
noresultvalues = true,
|
|
||||||
undeclaredname = true,
|
|
||||||
unusedvariable = true,
|
|
||||||
fillstruct = true,
|
|
||||||
stubmethods = true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
--[[
|
|
||||||
Copyright 2023 Oscar Wallberg
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
]]
|
|
||||||
|
|
||||||
return {
|
|
||||||
cmd = { "pylsp", },
|
|
||||||
single_file_support = true,
|
|
||||||
-- Reference: https://github.com/python-lsp/python-lsp-server/blob/develop/CONFIGURATION.md
|
|
||||||
settings = {
|
|
||||||
pylsp = {
|
|
||||||
-- configurationSources = { "flake8", "jedi_completion", "jedi_definition", "jedi_hover", "jedi_references", "jedi_signature_help", "jedi_symbols" },
|
|
||||||
plugins = {
|
|
||||||
flake8 = {
|
|
||||||
config = "tox.ini",
|
|
||||||
enabled = true,
|
|
||||||
-- executable = "flake8"
|
|
||||||
},
|
|
||||||
pyls_isort = { enabled = true, },
|
|
||||||
jedi_completion = {
|
|
||||||
enabled = true,
|
|
||||||
include_params = false,
|
|
||||||
include_class_objects = true,
|
|
||||||
fuzzy = true,
|
|
||||||
eager = true,
|
|
||||||
resolve_at_most = 25,
|
|
||||||
cache_for = {
|
|
||||||
"pandas",
|
|
||||||
"numpy",
|
|
||||||
"tensorflow",
|
|
||||||
"matplotlib",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
jedi_definition = {
|
|
||||||
enabled = true,
|
|
||||||
follow_imports = true,
|
|
||||||
follow_builtin_imports = true,
|
|
||||||
},
|
|
||||||
jedi_hover = { enabled = true, },
|
|
||||||
jedi_references = { enabled = true, },
|
|
||||||
jedi_signature_help = { enabled = true, },
|
|
||||||
jedi_symbols = {
|
|
||||||
enabled = true,
|
|
||||||
all_scopes = true,
|
|
||||||
include_import_symbols = true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
--[[
|
|
||||||
Copyright 2023 Oscar Wallberg
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
]]
|
|
||||||
|
|
||||||
return {
|
|
||||||
cmd = { "pyright-langserver", "--stdio", },
|
|
||||||
single_file_support = true,
|
|
||||||
-- see https://github.com/microsoft/pyright/blob/main/docs/configuration.md
|
|
||||||
-- and https://github.com/fannheyward/coc-pyright
|
|
||||||
settings = {
|
|
||||||
python = {
|
|
||||||
disableCompletion = false,
|
|
||||||
disableDiagnostics = false,
|
|
||||||
analysis = {
|
|
||||||
autoImportCompletions = true,
|
|
||||||
autoSearchPaths = true,
|
|
||||||
diagnosticMode = "workspace",
|
|
||||||
stubPath = "typings",
|
|
||||||
typeschedPaths = {},
|
|
||||||
diagnosticSeverityOverrides = {},
|
|
||||||
typeCheckingMode = "off",
|
|
||||||
useLibraryCodeForTypes = true,
|
|
||||||
},
|
|
||||||
completion = { importSupport = true, snippetSupport = true, },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
--[[
|
|
||||||
Copyright 2023 Oscar Wallberg
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
]]
|
|
||||||
|
|
||||||
return {
|
|
||||||
cmd = { "rust-analyzer", },
|
|
||||||
settings = {
|
|
||||||
-- https://github.com/rust-lang/rust-analyzer/blob/master/docs/user/generated_config.adoc
|
|
||||||
["rust-analyzer"] = {
|
|
||||||
cargo = {
|
|
||||||
-- Extra environment variables that will be set when running cargo, rustc
|
|
||||||
-- or other commands within the workspace. Useful for setting RUSTFLAGS.
|
|
||||||
extraEnv = {
|
|
||||||
OPENSSL_INCLUDE_DIR = "/usr/include/openssl-1.0/",
|
|
||||||
OPENSSL_LIB_DIR = "/usr/lib/openssl-1.0/",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
--[[ inlayHints = {
|
|
||||||
closingBraceHints = {
|
|
||||||
-- Whether to show inlay hints after a closing `}` to indicate what item it belongs to.
|
|
||||||
enable = false
|
|
||||||
},
|
|
||||||
} ]]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
+36
-16
@@ -14,6 +14,9 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local module_name = "lsp"
|
||||||
|
local utils = require("utils")
|
||||||
|
|
||||||
local P = {}
|
local P = {}
|
||||||
|
|
||||||
P._filetypes = nil
|
P._filetypes = nil
|
||||||
@@ -21,7 +24,7 @@ P._language_servers = nil
|
|||||||
|
|
||||||
P.capabilities = {}
|
P.capabilities = {}
|
||||||
|
|
||||||
P.spec = require("lsp.spec")
|
P.servers = require("lsp.servers")
|
||||||
|
|
||||||
function P._setup_diagnostic()
|
function P._setup_diagnostic()
|
||||||
vim.diagnostic.config({
|
vim.diagnostic.config({
|
||||||
@@ -216,9 +219,9 @@ function P.on_attach(client, bufnr)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function P.reload_server_buf(self, name)
|
function P.reload_server_buf(self, name)
|
||||||
local server_spec = self.spec[name]
|
local server = self.servers[name]
|
||||||
local ft_map = {}
|
local ft_map = {}
|
||||||
for _, ft in ipairs(server_spec.filetypes) do
|
for _, ft in ipairs(server.filetypes) do
|
||||||
ft_map[ft] = true
|
ft_map[ft] = true
|
||||||
end
|
end
|
||||||
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
||||||
@@ -238,8 +241,8 @@ function P.filetypes(self)
|
|||||||
if not self._filetypes then
|
if not self._filetypes then
|
||||||
self._filetypes = {}
|
self._filetypes = {}
|
||||||
local unique = {}
|
local unique = {}
|
||||||
for _, server_spec in pairs(self.spec) do
|
for _, cfg in pairs(self.servers) do
|
||||||
for _, ft in ipairs(server_spec.filetypes) do
|
for _, ft in ipairs(cfg.filetypes) do
|
||||||
if not unique[ft] then
|
if not unique[ft] then
|
||||||
table.insert(self._filetypes, ft)
|
table.insert(self._filetypes, ft)
|
||||||
unique[ft] = true
|
unique[ft] = true
|
||||||
@@ -254,23 +257,41 @@ end
|
|||||||
function P.language_servers(self)
|
function P.language_servers(self)
|
||||||
if not self._language_servers then
|
if not self._language_servers then
|
||||||
self._language_servers = {}
|
self._language_servers = {}
|
||||||
for server, _ in pairs(self.spec) do
|
for name, opts in pairs(self.servers) do
|
||||||
table.insert(self._language_servers, server)
|
if opts.dependencies ~= nil then
|
||||||
|
for _, dep in ipairs(opts.dependencies) do
|
||||||
|
if not utils.is_available(dep) then
|
||||||
|
utils.warn("Disabling " .. name .. " because " .. dep .. " is required but not installed",
|
||||||
|
module_name)
|
||||||
|
opts.enabled = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if opts.enabled == true then
|
||||||
|
opts.config = require("lsp.config." .. name)
|
||||||
|
table.insert(self._language_servers, name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return self._language_servers
|
return self._language_servers
|
||||||
end
|
end
|
||||||
|
|
||||||
function P.setup_server(self, server)
|
function P.setup_server(self, name)
|
||||||
|
local opts = self.servers[name]
|
||||||
|
|
||||||
|
if opts.enabled ~= true then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local lspconfig = require("lspconfig")
|
local lspconfig = require("lspconfig")
|
||||||
local server_spec = self.spec[server]
|
opts.config.filetypes = opts.filetypes
|
||||||
local cfg = require("lsp.config." .. server)
|
opts.config.root_dir = lspconfig.util.find_git_ancestor
|
||||||
cfg.filetypes = server_spec.filetypes
|
opts.config.capabilities = self.capabilities
|
||||||
cfg.root_dir = lspconfig.util.find_git_ancestor
|
opts.config.on_attach = self.on_attach
|
||||||
cfg.capabilities = self.capabilities
|
lspconfig[name].setup(opts.config)
|
||||||
cfg.on_attach = self.on_attach
|
self:reload_server_buf(name)
|
||||||
lspconfig[server].setup(cfg)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function P.setup(self)
|
function P.setup(self)
|
||||||
@@ -279,7 +300,6 @@ function P.setup(self)
|
|||||||
require("mason-lspconfig").setup_handlers({
|
require("mason-lspconfig").setup_handlers({
|
||||||
function (name)
|
function (name)
|
||||||
self:setup_server(name)
|
self:setup_server(name)
|
||||||
self:reload_server_buf(name)
|
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,8 +14,9 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
return {
|
local servers = {
|
||||||
clangd = {
|
clangd = {
|
||||||
|
enabled = true,
|
||||||
filetypes = {
|
filetypes = {
|
||||||
"c",
|
"c",
|
||||||
"cpp",
|
"cpp",
|
||||||
@@ -24,25 +25,36 @@ return {
|
|||||||
"cuda",
|
"cuda",
|
||||||
"proto",
|
"proto",
|
||||||
},
|
},
|
||||||
|
config = {},
|
||||||
},
|
},
|
||||||
cmake = {
|
cmake = {
|
||||||
|
enabled = true,
|
||||||
filetypes = {
|
filetypes = {
|
||||||
"cmake",
|
"cmake",
|
||||||
},
|
},
|
||||||
|
config = {},
|
||||||
},
|
},
|
||||||
diagnosticls = {
|
diagnosticls = {
|
||||||
|
enabled = true,
|
||||||
filetypes = {
|
filetypes = {
|
||||||
"python",
|
"python",
|
||||||
"lua",
|
"lua",
|
||||||
"sh",
|
"sh",
|
||||||
},
|
},
|
||||||
|
dependencies = {
|
||||||
|
"npm",
|
||||||
|
},
|
||||||
|
config = {},
|
||||||
},
|
},
|
||||||
lua_ls = {
|
lua_ls = {
|
||||||
|
enabled = true,
|
||||||
filetypes = {
|
filetypes = {
|
||||||
"lua",
|
"lua",
|
||||||
},
|
},
|
||||||
|
config = {},
|
||||||
},
|
},
|
||||||
lemminx = {
|
lemminx = {
|
||||||
|
enabled = true,
|
||||||
filetypes = {
|
filetypes = {
|
||||||
"xml",
|
"xml",
|
||||||
"xsd",
|
"xsd",
|
||||||
@@ -50,39 +62,32 @@ return {
|
|||||||
"xslt",
|
"xslt",
|
||||||
"svg",
|
"svg",
|
||||||
},
|
},
|
||||||
|
config = {},
|
||||||
},
|
},
|
||||||
bashls = {
|
bashls = {
|
||||||
|
enabled = true,
|
||||||
filetypes = {
|
filetypes = {
|
||||||
"sh",
|
"sh",
|
||||||
},
|
},
|
||||||
|
dependencies = {
|
||||||
|
"npm",
|
||||||
|
},
|
||||||
|
config = {},
|
||||||
},
|
},
|
||||||
groovyls = {
|
groovyls = {
|
||||||
|
enabled = true,
|
||||||
filetypes = {
|
filetypes = {
|
||||||
"groovy",
|
"groovy",
|
||||||
},
|
},
|
||||||
},
|
config = {},
|
||||||
rust_analyzer = {
|
|
||||||
filetypes = {
|
|
||||||
"rust",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
gopls = {
|
|
||||||
filetypes = {
|
|
||||||
"go",
|
|
||||||
"gomod",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
golangci_lint_ls = {
|
|
||||||
filetypes = {
|
|
||||||
"go",
|
|
||||||
"gomod",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
jedi_language_server = {
|
jedi_language_server = {
|
||||||
|
enabled = true,
|
||||||
filetypes = {
|
filetypes = {
|
||||||
"python",
|
"python",
|
||||||
},
|
},
|
||||||
|
config = {},
|
||||||
},
|
},
|
||||||
-- pyright = { 'python' },
|
|
||||||
-- pylsp = { 'python' },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return servers
|
||||||
@@ -23,6 +23,11 @@ local plugins = {
|
|||||||
lazy = false,
|
lazy = false,
|
||||||
config = function () require("config.vscode") end,
|
config = function () require("config.vscode") end,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"rcarriga/nvim-notify",
|
||||||
|
priority = 900,
|
||||||
|
config = function () require("config.nvim-notify") end,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"rafamadriz/friendly-snippets",
|
"rafamadriz/friendly-snippets",
|
||||||
},
|
},
|
||||||
|
|||||||
+24
-1
@@ -43,7 +43,7 @@ end
|
|||||||
--- @param exe string: Array to look for
|
--- @param exe string: Array to look for
|
||||||
function M.assert_available(exe)
|
function M.assert_available(exe)
|
||||||
if not M.is_available(exe) then
|
if not M.is_available(exe) then
|
||||||
error("Missing executable '" .. exe .. "'.")
|
M.notify("Missing executable '" .. exe .. "'.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -65,4 +65,27 @@ function M.assert_python3_module(mod)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.notify(msg, title, level)
|
||||||
|
if title and not pcall(require, "notify") then
|
||||||
|
msg = "[" .. title .. "] " .. msg
|
||||||
|
end
|
||||||
|
vim.notify(msg, level, { title = title, })
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.debug(msg, title)
|
||||||
|
M.notify(msg, title, vim.log.levels.DEBUG)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.info(msg, title)
|
||||||
|
M.notify(msg, title, vim.log.levels.INFO)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.warn(msg, title)
|
||||||
|
M.notify(msg, title, vim.log.levels.WARN)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.err(msg, title)
|
||||||
|
M.notify(msg, title, vim.log.levels.ERROR)
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
Reference in New Issue
Block a user