@ -1,10 +0,0 @@ | |||||
return { | |||||
{ | |||||
'ChuufMaster/buffer-vacuum', | |||||
opts = { | |||||
max_buffers = 10, | |||||
count_pinned_buffers = false, | |||||
enable_messages = false, | |||||
} | |||||
}, | |||||
} |
@ -1,9 +0,0 @@ | |||||
return { | |||||
"lukas-reineke/indent-blankline.nvim", | |||||
main = "ibl", | |||||
opts = { | |||||
exclude = { | |||||
filetypes = { "dashboard" }, | |||||
} | |||||
} | |||||
} |
@ -1,252 +0,0 @@ | |||||
return { | |||||
"neovim/nvim-lspconfig", | |||||
event = { "BufReadPre", "BufNewFile" }, | |||||
dependencies = { | |||||
"hrsh7th/cmp-nvim-lsp", | |||||
{ "antosha417/nvim-lsp-file-operations", config = true }, | |||||
}, | |||||
config = function() | |||||
-- import lspconfig plugin | |||||
local lspconfig = require("lspconfig") | |||||
local util = require("lspconfig.util") | |||||
-- import cmp-nvim-lsp plugin | |||||
local cmp_nvim_lsp = require("cmp_nvim_lsp") | |||||
local keymap = vim.keymap | |||||
local opts = { noremap = true, silent = true } | |||||
local on_attach = function(_, bufnr) | |||||
opts.buffer = bufnr | |||||
-- set keybinds | |||||
opts.desc = "Show LSP references" | |||||
keymap.set("n", "gr", "<cmd>Telescope lsp_references<CR>", opts) -- show definition, references | |||||
opts.desc = "Go to declaration" | |||||
keymap.set("n", "gD", vim.lsp.buf.declaration, opts) -- go to declaration | |||||
opts.desc = "Show LSP definitions" | |||||
keymap.set("n", "gd", "<cmd>Telescope lsp_definitions<CR>", opts) -- show lsp definitions | |||||
opts.desc = "Show LSP implementations" | |||||
keymap.set("n", "gi", "<cmd>Telescope lsp_implementations<CR>", opts) -- show lsp implementations | |||||
opts.desc = "Show LSP type definitions" | |||||
keymap.set("n", "gt", "<cmd>Telescope lsp_type_definitions<CR>", opts) -- show lsp type definitions | |||||
opts.desc = "See available code actions" | |||||
keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts) -- see available code actions, in visual mode will apply to selection | |||||
opts.desc = "Smart rename" | |||||
keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts) -- smart rename | |||||
opts.desc = "Show buffer diagnostics" | |||||
keymap.set("n", "<leader>D", "<cmd>Telescope diagnostics bufnr=0<CR>", opts) -- show diagnostics for file | |||||
opts.desc = "Show line diagnostics" | |||||
keymap.set("n", "<leader>d", vim.diagnostic.open_float, opts) -- show diagnostics for line | |||||
opts.desc = "Go to previous diagnostic" | |||||
keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) -- jump to previous diagnostic in buffer | |||||
-- opts.desc = "Go to previous diagnostic" | |||||
-- keymap.set("n", "<leader>pd", vim.diagnostic.goto_prev, opts) -- jump to previous diagnostic in buffer | |||||
opts.desc = "Go to next diagnostic" | |||||
keymap.set("n", "]d", vim.diagnostic.goto_next, opts) -- jump to next diagnostic in buffer | |||||
-- opts.desc = "Go to next diagnostic" | |||||
-- keymap.set("n", "<leader>nd", vim.diagnostic.goto_next, opts) -- jump to next diagnostic in buffer | |||||
opts.desc = "Go to previous diagnostic (error only)" | |||||
keymap.set("n", "[e", function() | |||||
vim.diagnostic.goto_prev({ severity = vim.diagnostic.severity.ERROR }) | |||||
end, opts) | |||||
opts.desc = "Go to next diagnostic (error only)" | |||||
keymap.set("n", "]e", function() | |||||
vim.diagnostic.goto_next({ severity = vim.diagnostic.severity.ERROR }) | |||||
end, opts) | |||||
opts.desc = "Show documentation for what is under cursor" | |||||
keymap.set("n", "<leader>ld", vim.diagnostic.setqflist, opts) -- show documentation for what is under cursor | |||||
opts.desc = "Show documentation for what is under cursor" | |||||
keymap.set("n", "K", vim.lsp.buf.hover, opts) -- show documentation for what is under cursor | |||||
end | |||||
-- override default floating window border if not set | |||||
local orig_util_open_floating_preview = vim.lsp.util.open_floating_preview | |||||
---@diagnostic disable-next-line: duplicate-set-field | |||||
function vim.lsp.util.open_floating_preview(contents, syntax, options, ...) | |||||
options = options or {} | |||||
options.border = options.border or "rounded" | |||||
return orig_util_open_floating_preview(contents, syntax, options, ...) | |||||
end | |||||
-- used to enable autocompletion (assign to every lsp server config) | |||||
local capabilities = cmp_nvim_lsp.default_capabilities() | |||||
-- Change the Diagnostic symbols in the sign column (gutter) | |||||
local signs = { Error = " ", Warn = " ", Hint = " ", Info = " " } | |||||
for type, icon in pairs(signs) do | |||||
local hl = "DiagnosticSign" .. type | |||||
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl }) | |||||
end | |||||
lspconfig.html.setup({ | |||||
capabilities = capabilities, | |||||
on_attach = on_attach, | |||||
}) | |||||
-- Function to detect the operating system | |||||
local function get_os() | |||||
local handle = io.popen("uname") | |||||
if not handle then | |||||
return error("Failed to detect operating system") | |||||
end | |||||
local result = handle:read("*a") | |||||
handle:close() | |||||
return result:lower():gsub("%s+", "") | |||||
end | |||||
-- Set the base path based on the operating system | |||||
local os = get_os() | |||||
local base_path = "" | |||||
if os == "darwin" then | |||||
base_path = "/opt/homebrew/lib/node_modules" | |||||
elseif os == "linux" then | |||||
base_path = "/usr/local/lib/node_modules" | |||||
end | |||||
lspconfig.tsserver.setup({ | |||||
init_options = { | |||||
plugins = { | |||||
{ | |||||
name = "@vue/typescript-plugin", | |||||
location = base_path .. "/@vue/typescript-plugin", | |||||
languages = { "javascript", "typescript", "vue" }, | |||||
}, | |||||
}, | |||||
}, | |||||
filetypes = { | |||||
"javascript", | |||||
"typescript", | |||||
"vue", | |||||
}, | |||||
capabilities = capabilities, | |||||
}) | |||||
local function get_typescript_server_path(root_dir) | |||||
local global_ts = base_path .. "/typescript/lib" | |||||
local found_ts = "" | |||||
local function check_dir(path) | |||||
found_ts = util.path.join(path, "node_modules", "typescript", "lib") | |||||
if util.path.exists(found_ts) then | |||||
return path | |||||
end | |||||
end | |||||
if util.search_ancestors(root_dir, check_dir) then | |||||
return found_ts | |||||
else | |||||
return global_ts | |||||
end | |||||
end | |||||
lspconfig.volar.setup({ | |||||
capabilities = capabilities, | |||||
on_attach = on_attach, | |||||
filetypes = { | |||||
"javascript", | |||||
"typescript", | |||||
"vue", | |||||
}, | |||||
on_new_config = function(new_config, new_root_dir) | |||||
new_config.init_options.typescript.tsdk = get_typescript_server_path(new_root_dir) | |||||
end, | |||||
}) | |||||
-- configure css server | |||||
lspconfig["cssls"].setup({ | |||||
capabilities = capabilities, | |||||
on_attach = on_attach, | |||||
}) | |||||
-- configure php server | |||||
lspconfig.intelephense.setup({ | |||||
root_dir = function(pattern) | |||||
---@diagnostic disable-next-line: undefined-field | |||||
local cwd = vim.loop.cwd() | |||||
local root = util.root_pattern("composer.json")(pattern) | |||||
-- prefer cwd if root is a descendant | |||||
return util.path.is_descendant(cwd, root) and cwd or root | |||||
end, | |||||
capabilities = capabilities, | |||||
on_attach = on_attach, | |||||
init_options = { | |||||
licenceKey = vim.fn.expand("$HOME/.local/share/nvim/intelephense-licence.txt"), | |||||
}, | |||||
settings = { | |||||
intelephense = { | |||||
format = { | |||||
enable = true, | |||||
sortUseStatements = false, | |||||
} | |||||
}, | |||||
}, | |||||
}) | |||||
lspconfig.gopls.setup({ | |||||
on_attach = on_attach, | |||||
capabilities = capabilities, | |||||
cmd = { "gopls" }, | |||||
filetypes = { "go", "gomod", "gowork", "gotmpl" }, | |||||
root_dir = util.root_pattern("go.work", "go.mod", ".git"), | |||||
settings = { | |||||
gopls = { | |||||
completeUnimported = true, | |||||
usePlaceholders = true, | |||||
analyses = { | |||||
unusedparams = true, | |||||
}, | |||||
}, | |||||
}, | |||||
}) | |||||
-- configure lua server (with special settings) | |||||
lspconfig["lua_ls"].setup({ | |||||
capabilities = capabilities, | |||||
on_attach = on_attach, | |||||
settings = { -- custom settings for lua | |||||
Lua = { | |||||
-- make the language server recognize "vim" global | |||||
diagnostics = { | |||||
globals = { "vim" }, | |||||
}, | |||||
workspace = { | |||||
-- make language server aware of runtime files | |||||
library = { | |||||
[vim.fn.expand("$VIMRUNTIME/lua")] = true, | |||||
[vim.fn.stdpath("config") .. "/lua"] = true, | |||||
}, | |||||
}, | |||||
}, | |||||
}, | |||||
}) | |||||
-- configure python server | |||||
lspconfig["dartls"].setup({ | |||||
capabilities = capabilities, | |||||
on_attach = on_attach, | |||||
}) | |||||
vim.diagnostic.config({ | |||||
virtual_text = { | |||||
prefix = '', | |||||
}, | |||||
}) | |||||
end, | |||||
} |
@ -1,58 +0,0 @@ | |||||
return { | |||||
"williamboman/mason.nvim", | |||||
dependencies = { | |||||
"williamboman/mason-lspconfig.nvim", | |||||
"WhoIsSethDaniel/mason-tool-installer.nvim", | |||||
}, | |||||
config = function() | |||||
-- import mason | |||||
local mason = require("mason") | |||||
-- import mason-lspconfig | |||||
local mason_lspconfig = require("mason-lspconfig") | |||||
local mason_tool_installer = require("mason-tool-installer") | |||||
-- enable mason and configure icons | |||||
mason.setup({ | |||||
ui = { | |||||
icons = { | |||||
package_installed = "✓", | |||||
package_pending = "➜", | |||||
package_uninstalled = "✗", | |||||
}, | |||||
}, | |||||
}) | |||||
mason_lspconfig.setup({ | |||||
-- list of servers for mason to install | |||||
ensure_installed = { | |||||
"tsserver", | |||||
"html", | |||||
"cssls", | |||||
"lua_ls", | |||||
"emmet_ls", | |||||
"intelephense", | |||||
}, | |||||
automatic_installation = true, | |||||
}) | |||||
mason_tool_installer.setup({ | |||||
ensure_installed = { | |||||
"prettier", | |||||
"prettierd", | |||||
"eslint", | |||||
"eslint_d", | |||||
"jsonlint", | |||||
"markdownlint", | |||||
"phpcbf", | |||||
"phpcs", | |||||
"golangci-lint", | |||||
"hadolint", | |||||
"gofumpt", | |||||
"goimports", | |||||
}, | |||||
automatic_installation = true, | |||||
}) | |||||
end, | |||||
} |
@ -0,0 +1,265 @@ | |||||
return { | |||||
"neovim/nvim-lspconfig", | |||||
event = { "BufReadPre", "BufNewFile" }, | |||||
dependencies = { | |||||
{ "hrsh7th/cmp-nvim-lsp" }, | |||||
{ "antosha417/nvim-lsp-file-operations", config = true }, | |||||
{ "williamboman/mason.nvim", config = true }, | |||||
{ "williamboman/mason-lspconfig.nvim" }, | |||||
{ "WhoIsSethDaniel/mason-tool-installer.nvim" }, | |||||
{ "j-hui/fidget.nvim", opts = {} }, | |||||
{ "folke/neodev.nvim", opts = {} }, | |||||
}, | |||||
config = function() | |||||
-- import lspconfig plugin | |||||
local lspconfig = require("lspconfig") | |||||
local util = require("lspconfig.util") | |||||
-- import cmp-nvim-lsp plugin | |||||
local cmp_nvim_lsp = require("cmp_nvim_lsp") | |||||
local keymap = vim.keymap | |||||
vim.api.nvim_create_autocmd("LspAttach", { | |||||
group = vim.api.nvim_create_augroup("lsp-attach", { clear = true }), | |||||
callback = function(event) | |||||
local opts = { noremap = true, silent = true } | |||||
-- set keybinds | |||||
opts.desc = "Show LSP references" | |||||
keymap.set("n", "gr", "<cmd>Telescope lsp_references<CR>", opts) -- show definition, references | |||||
opts.desc = "Go to declaration" | |||||
keymap.set("n", "gD", vim.lsp.buf.declaration, opts) -- go to declaration | |||||
opts.desc = "Show LSP definitions" | |||||
keymap.set("n", "gd", "<cmd>Telescope lsp_definitions<CR>", opts) -- show lsp definitions | |||||
opts.desc = "Show LSP implementations" | |||||
keymap.set("n", "gi", "<cmd>Telescope lsp_implementations<CR>", opts) -- show lsp implementations | |||||
opts.desc = "Show LSP type definitions" | |||||
keymap.set("n", "gt", "<cmd>Telescope lsp_type_definitions<CR>", opts) -- show lsp type definitions | |||||
opts.desc = "See available code actions" | |||||
keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts) -- see available code actions, in visual mode will apply to selection | |||||
opts.desc = "Smart rename" | |||||
keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts) -- smart rename | |||||
opts.desc = "Show buffer diagnostics" | |||||
keymap.set("n", "<leader>D", "<cmd>Telescope diagnostics bufnr=0<CR>", opts) -- show diagnostics for file | |||||
opts.desc = "Show line diagnostics" | |||||
keymap.set("n", "<leader>d", vim.diagnostic.open_float, opts) -- show diagnostics for line | |||||
opts.desc = "Go to previous diagnostic" | |||||
keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) -- jump to previous diagnostic in buffer | |||||
opts.desc = "Go to next diagnostic" | |||||
keymap.set("n", "]d", vim.diagnostic.goto_next, opts) -- jump to next diagnostic in buffer | |||||
opts.desc = "Go to previous diagnostic (error only)" | |||||
keymap.set("n", "[e", function() | |||||
vim.diagnostic.goto_prev({ severity = vim.diagnostic.severity.ERROR }) | |||||
end, opts) | |||||
opts.desc = "Go to next diagnostic (error only)" | |||||
keymap.set("n", "]e", function() | |||||
vim.diagnostic.goto_next({ severity = vim.diagnostic.severity.ERROR }) | |||||
end, opts) | |||||
opts.desc = "Show documentation for what is under cursor" | |||||
keymap.set("n", "<leader>ld", vim.diagnostic.setqflist, opts) -- show documentation for what is under cursor | |||||
opts.desc = "Show documentation for what is under cursor" | |||||
keymap.set("n", "K", vim.lsp.buf.hover, opts) -- show documentation for what is under cursor | |||||
local client = vim.lsp.get_client_by_id(event.data.client_id) | |||||
if client and client.server_capabilities.documentHighlightProvider then | |||||
vim.api.nvim_create_autocmd("LspDetach", { | |||||
group = vim.api.nvim_create_augroup("lsp-detach", { clear = true }), | |||||
callback = function(event2) | |||||
vim.lsp.buf.clear_references() | |||||
end, | |||||
}) | |||||
end | |||||
-- The following autocommand is used to enable inlay hints in your | |||||
-- code, if the language server you are using supports them | |||||
-- | |||||
-- This may be unwanted, since they displace some of your code | |||||
if client and client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then | |||||
opts.desc = "Toggle Inlay Hints" | |||||
keymap.set("n", "<leader>th", function() | |||||
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({})) | |||||
end, opts) | |||||
end | |||||
end, | |||||
}) | |||||
local capabilities = vim.lsp.protocol.make_client_capabilities() | |||||
capabilities = vim.tbl_deep_extend("force", capabilities, require("cmp_nvim_lsp").default_capabilities()) | |||||
-- Function to detect the operating system | |||||
local function get_os() | |||||
local handle = io.popen("uname") | |||||
if not handle then | |||||
return error("Failed to detect operating system") | |||||
end | |||||
local result = handle:read("*a") | |||||
handle:close() | |||||
return result:lower():gsub("%s+", "") | |||||
end | |||||
-- Set the base path based on the operating system | |||||
local os = get_os() | |||||
local base_path = "" | |||||
if os == "darwin" then | |||||
base_path = "/opt/homebrew/lib/node_modules" | |||||
elseif os == "linux" then | |||||
base_path = "/usr/local/lib/node_modules" | |||||
end | |||||
local function get_typescript_server_path(root_dir) | |||||
local global_ts = base_path .. "/typescript/lib" | |||||
local found_ts = "" | |||||
local function check_dir(path) | |||||
found_ts = util.path.join(path, "node_modules", "typescript", "lib") | |||||
if util.path.exists(found_ts) then | |||||
return path | |||||
end | |||||
end | |||||
if util.search_ancestors(root_dir, check_dir) then | |||||
return found_ts | |||||
else | |||||
return global_ts | |||||
end | |||||
end | |||||
local servers = { | |||||
tsserver = { | |||||
init_options = { | |||||
plugins = { | |||||
{ | |||||
name = "@vue/typescript-plugin", | |||||
location = base_path .. "/@vue/typescript-plugin", | |||||
languages = { "javascript", "typescript", "vue" }, | |||||
}, | |||||
}, | |||||
}, | |||||
filetypes = { | |||||
"javascript", | |||||
"typescript", | |||||
"vue", | |||||
}, | |||||
}, | |||||
volar = { | |||||
filetypes = { | |||||
"javascript", | |||||
"typescript", | |||||
"vue", | |||||
}, | |||||
on_new_config = function(new_config, new_root_dir) | |||||
new_config.init_options.typescript.tsdk = get_typescript_server_path(new_root_dir) | |||||
end, | |||||
}, | |||||
cssls = {}, | |||||
intelephense = { | |||||
root_dir = function(pattern) | |||||
---@diagnostic disable-next-line: undefined-field | |||||
local cwd = vim.loop.cwd() | |||||
local root = util.root_pattern("composer.json")(pattern) | |||||
-- prefer cwd if root is a descendant | |||||
return util.path.is_descendant(cwd, root) and cwd or root | |||||
end, | |||||
init_options = { | |||||
licenceKey = vim.fn.expand("$HOME/.local/share/nvim/intelephense-licence.txt"), | |||||
}, | |||||
settings = { | |||||
intelephense = { | |||||
format = { | |||||
enable = true, | |||||
sortUseStatements = false, | |||||
}, | |||||
}, | |||||
}, | |||||
}, | |||||
gopls = { | |||||
cmd = { "gopls" }, | |||||
filetypes = { "go", "gomod", "gowork", "gotmpl" }, | |||||
root_dir = util.root_pattern("go.work", "go.mod", ".git"), | |||||
settings = { | |||||
gopls = { | |||||
completeUnimported = true, | |||||
usePlaceholders = true, | |||||
analyses = { | |||||
unusedparams = true, | |||||
}, | |||||
}, | |||||
}, | |||||
}, | |||||
lua_ls = { | |||||
settings = { -- custom settings for lua | |||||
Lua = { | |||||
-- make the language server recognize "vim" global | |||||
diagnostics = { | |||||
globals = { "vim" }, | |||||
}, | |||||
workspace = { | |||||
-- make language server aware of runtime files | |||||
library = { | |||||
[vim.fn.expand("$VIMRUNTIME/lua")] = true, | |||||
[vim.fn.stdpath("config") .. "/lua"] = true, | |||||
}, | |||||
}, | |||||
}, | |||||
}, | |||||
}, | |||||
dartls = { | |||||
cmd = { "dart", "language-server", "--protocol=lsp" }, | |||||
}, | |||||
} | |||||
require("mason").setup() | |||||
local ensure_installed = vim.tbl_keys(servers or {}) | |||||
vim.list_extend(ensure_installed, { | |||||
"stylua", | |||||
"prettier", | |||||
"prettierd", | |||||
"eslint", | |||||
"eslint_d", | |||||
"jsonlint", | |||||
"markdownlint", | |||||
"phpcbf", | |||||
"phpcs", | |||||
"golangci-lint", | |||||
"hadolint", | |||||
"gofumpt", | |||||
"goimports", | |||||
}) | |||||
require("mason-tool-installer").setup({ | |||||
ensure_installed = ensure_installed, | |||||
run_on_start = false, | |||||
}) | |||||
require("mason-lspconfig").setup({ | |||||
handlers = { | |||||
function(server_name) | |||||
local server = servers[server_name] or {} | |||||
server.capabilities = vim.tbl_deep_extend("force", {}, capabilities, server.capabilities or {}) | |||||
require("lspconfig")[server_name].setup(server) | |||||
end, | |||||
}, | |||||
}) | |||||
end, | |||||
} |
@ -1,6 +1,7 @@ | |||||
return { | return { | ||||
"chrisgrieser/nvim-scissors", | "chrisgrieser/nvim-scissors", | ||||
dependencies = "nvim-telescope/telescope.nvim", -- optional | |||||
event = "VeryLazy", | |||||
dependencies = "nvim-telescope/telescope.nvim", | |||||
opts = { | opts = { | ||||
snippetDir = "~/.config/nvim/snippets", | snippetDir = "~/.config/nvim/snippets", | ||||
} | } | ||||
@ -1,72 +0,0 @@ | |||||
#:schema https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json | |||||
version = 2 | |||||
final_space = true | |||||
console_title_template = '{{ .Shell }} in {{ .Folder }}' | |||||
[[blocks]] | |||||
type = 'prompt' | |||||
alignment = 'left' | |||||
newline = true | |||||
[[blocks.segments]] | |||||
type = 'path' | |||||
style = 'plain' | |||||
background = 'transparent' | |||||
foreground = 'blue' | |||||
template = '{{ .Path }}' | |||||
[blocks.segments.properties] | |||||
style = 'full' | |||||
[[blocks.segments]] | |||||
type = 'git' | |||||
style = 'plain' | |||||
foreground = 'p:grey' | |||||
background = 'transparent' | |||||
template = ' {{ .HEAD }}{{ if or (.Working.Changed) (.Staging.Changed) }}*{{ end }} <cyan>{{ if gt .Behind 0 }}⇣{{ end }}{{ if gt .Ahead 0 }}⇡{{ end }}</>' | |||||
[blocks.segments.properties] | |||||
fetch_status = true | |||||
[[blocks]] | |||||
type = 'rprompt' | |||||
overflow = 'hidden' | |||||
[[blocks.segments]] | |||||
type = 'executiontime' | |||||
style = 'plain' | |||||
foreground = 'yellow' | |||||
background = 'transparent' | |||||
template = '{{ .FormattedMs }}' | |||||
[blocks.segments.properties] | |||||
threshold = 5000 | |||||
[[blocks]] | |||||
type = 'prompt' | |||||
alignment = 'left' | |||||
newline = true | |||||
[[blocks.segments]] | |||||
type = 'text' | |||||
style = 'plain' | |||||
foreground_templates = [ | |||||
"{{if gt .Code 0}}red{{end}}", | |||||
"{{if eq .Code 0}}magenta{{end}}", | |||||
] | |||||
background = 'transparent' | |||||
template = '❯' | |||||
[transient_prompt] | |||||
foreground_templates = [ | |||||
"{{if gt .Code 0}}red{{end}}", | |||||
"{{if eq .Code 0}}magenta{{end}}", | |||||
] | |||||
background = 'transparent' | |||||
template = '❯ ' | |||||
[secondary_prompt] | |||||
foreground = 'magenta' | |||||
background = 'transparent' | |||||
template = '❯❯ ' |