From 63feeb9f369fc6176e85c1c2d8fcc863caad1946 Mon Sep 17 00:00:00 2001 From: Robert Günzler Date: Tue, 10 Feb 2026 12:32:48 +0100 Subject: start new MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Robert Günzler --- .config/nvim/lua/plugins/blink.lua | 94 ++++++++++++++++++++++++++ .config/nvim/lua/plugins/calcium.lua | 15 +++++ .config/nvim/lua/plugins/colorizer.lua | 15 +++++ .config/nvim/lua/plugins/fzf.lua | 103 ++++++++++++++++++++++++++++ .config/nvim/lua/plugins/gentoo.lua | 15 +++++ .config/nvim/lua/plugins/git.lua | 116 ++++++++++++++++++++++++++++++++ .config/nvim/lua/plugins/icons.lua | 13 ++++ .config/nvim/lua/plugins/indent.lua | 30 +++++++++ .config/nvim/lua/plugins/lsp.lua | 6 ++ .config/nvim/lua/plugins/markdown.lua | 82 ++++++++++++++++++++++ .config/nvim/lua/plugins/mini.lua | 26 +++++++ .config/nvim/lua/plugins/oil.lua | 21 ++++++ .config/nvim/lua/plugins/snippets.lua | 13 ++++ .config/nvim/lua/plugins/treesitter.lua | 93 +++++++++++++++++++++++++ .config/nvim/lua/plugins/whichkey.lua | 10 +++ 15 files changed, 652 insertions(+) create mode 100644 .config/nvim/lua/plugins/blink.lua create mode 100644 .config/nvim/lua/plugins/calcium.lua create mode 100644 .config/nvim/lua/plugins/colorizer.lua create mode 100644 .config/nvim/lua/plugins/fzf.lua create mode 100644 .config/nvim/lua/plugins/gentoo.lua create mode 100644 .config/nvim/lua/plugins/git.lua create mode 100644 .config/nvim/lua/plugins/icons.lua create mode 100644 .config/nvim/lua/plugins/indent.lua create mode 100644 .config/nvim/lua/plugins/lsp.lua create mode 100644 .config/nvim/lua/plugins/markdown.lua create mode 100644 .config/nvim/lua/plugins/mini.lua create mode 100644 .config/nvim/lua/plugins/oil.lua create mode 100644 .config/nvim/lua/plugins/snippets.lua create mode 100644 .config/nvim/lua/plugins/treesitter.lua create mode 100644 .config/nvim/lua/plugins/whichkey.lua (limited to '.config/nvim/lua/plugins') diff --git a/.config/nvim/lua/plugins/blink.lua b/.config/nvim/lua/plugins/blink.lua new file mode 100644 index 0000000..1122bcc --- /dev/null +++ b/.config/nvim/lua/plugins/blink.lua @@ -0,0 +1,94 @@ +return { + { + 'saghen/blink.cmp', + version = '1.*', + + lazy = false, + + dependencies = { + { 'L3MON4D3/LuaSnip' }, + }, + + init = function() + vim.opt.completeopt = { 'menu', 'menuone', 'noselect' } + vim.opt.shortmess:append('c') + vim.opt.pumheight = 20 -- max height of completion window + + local hl = vim.api.nvim_set_hl + hl(0, 'BlinkCmpSource', { link = 'Comment', force = true }) + hl(0, 'BlinkCmpLabelDescription', { link = 'Comment', force = true }) + end, + + opts_extend = { 'sources.default' }, + + opts = { + -- TODO: + -- 'prefer_rust_with_warning', requires nightly rust, due to: + -- https://github.com/rust-lang/rust/issues/86656 + fuzzy = { + implementation = 'lua', + sorts = { + function(a, b) + local prio = { + snippets = 99, + -- everyting else 0 + } + local a_priority = prio[a.source_id] or 0 + local b_priority = prio[b.source_id] or 0 + if a_priority ~= b_priority then return a_priority > b_priority end + end, + -- defaults + 'score', + 'sort_text' + }, + }, + + appearance = { + -- fallback to cmp highlight names + use_nvim_cmp_as_default = true, + -- adjusts spacing to ensure icons are aligned + -- nerd_font_variant = 'normal', + }, + + sources = { + providers = { + buffer = { min_keyword_length = 3 }, + }, + }, + + completion = { + documentation = { auto_show = true }, + menu = { + draw = { + columns = { + { 'kind_icon' }, + { 'label', 'label_description', gap = 1 }, + { 'source_name' }, + }, + }, + }, + }, + + signature = { + enabled = true, + window = { scrollbar = false }, -- BUG: weird artifacts + }, + + keymap = { + [''] = { 'show', 'show_documentation', 'hide_documentation' }, + [''] = { 'cancel', 'fallback' }, + [''] = { 'select_and_accept' }, + [''] = { 'select_prev', 'fallback' }, + [''] = { 'select_next', 'fallback' }, + [''] = { 'scroll_documentation_up', 'fallback' }, + [''] = { 'scroll_documentation_down', 'fallback' }, + [''] = { 'select_and_accept', 'fallback' }, + [''] = { 'snippet_forward', 'fallback' }, + [''] = { 'snippet_backward', 'fallback' }, + -- [''] = { 'show', 'hide', 'fallback' }, + }, + + snippets = { preset = 'luasnip' }, + }, + }, +} diff --git a/.config/nvim/lua/plugins/calcium.lua b/.config/nvim/lua/plugins/calcium.lua new file mode 100644 index 0000000..f0ab78c --- /dev/null +++ b/.config/nvim/lua/plugins/calcium.lua @@ -0,0 +1,15 @@ +return { + { + 'necrom4/calcium.nvim', + cmd = {'Calcium'}, + opts = { + notifications = false, + default_mode = 'replace', + }, + keys = { + { mode = {'n', 'v'}, 'gl', '', desc = 'Calcium' }, + { mode = {'n', 'v'}, 'glr', ':Calcium replace', desc = 'Calcium replace', silent = true }, + { mode = {'n', 'v'}, 'gla', ':Calcium append', desc = 'Calcium append', silent = true }, + }, + } +} diff --git a/.config/nvim/lua/plugins/colorizer.lua b/.config/nvim/lua/plugins/colorizer.lua new file mode 100644 index 0000000..2608ae6 --- /dev/null +++ b/.config/nvim/lua/plugins/colorizer.lua @@ -0,0 +1,15 @@ +return { + { + 'NvChad/nvim-colorizer.lua', + -- 'norcalli/nvim-colorizer.lua', + lazy = false, + opts = { + name = true, + RRGGBB = true, + RRGGBBAA = true, + rgb_fn = true, + hsl_fn = true, + mode = 'background', + }, + }, +} diff --git a/.config/nvim/lua/plugins/fzf.lua b/.config/nvim/lua/plugins/fzf.lua new file mode 100644 index 0000000..efee6ef --- /dev/null +++ b/.config/nvim/lua/plugins/fzf.lua @@ -0,0 +1,103 @@ +return { + { + enabled = true, + 'ibhagwan/fzf-lua', + lazy = false, + dependencies = { + 'echasnovski/mini.icons', + }, + config = function() + local fzf = require('fzf-lua') + fzf.register_ui_select() + fzf.setup({ + -- PROFILE + { 'default' }, + -- OPTIONS + winopts = { + split = 'belowright 20new', + border = 'none', + preview = { + border = 'none', + }, + -- on_create = function() end, + }, + keymap = { + fzf = { + true, + ['ctrl-n'] = 'down', + ['ctrl-p'] = 'up', + }, + }, + -- actions = { + -- files = { + -- ['ctrl-q'] = { fn = fzf.actions.file_sel_to_qf }, + -- }, + -- }, + fzf_colors = true, + -- PICKER CONFIG + files = { + file_icons = true, + }, + marks = { + marks = '[a-zA-Z]', + } + }) + end, + keys = { + { mode = 'n', ';', 'FzfLua', desc = 'fzf: select' }, + { mode = 'n', ';/', 'FzfLua blines', desc = 'fzf: current_buffer_fuzzy_find' }, + { mode = 'n', ';b', 'FzfLua buffers', desc = 'fzf: buffers' }, + { mode = 'n', ';f', 'FzfLua files', desc = 'fzf: find_files' }, + { mode = 'n', ';g', 'FzfLua live_grep', desc = 'fzf: live_grep' }, + { mode = 'n', ';d', 'FzfLua diagnostics_workspace', desc = 'fzf: workspace diagnostics' }, + { mode = 'n', ';D', 'FzfLua diagnostics_document', desc = 'fzf: document diagnostics' }, + { mode = 'n', ';h', 'FzfLua helptags', desc = 'fzf: help' }, + { mode = 'n', ';s', 'FzfLua lsp_document_symbols', desc = 'fzf: document symbols' }, + { mode = 'n', ';w', 'FzfLua lsp_live_workspace_symbols', desc = 'fzf: workspace symbols' }, + { mode = 'n', ';m', 'FzfLua marks', desc = 'fzf: marks' }, + { + mode = 'n', + ';v', + function() + require('fzf-lua').files({ cwd = vim.fn.stdpath('config') }) + end, + desc = 'fzf: vim_config', + }, + -- { + -- mode = 'n', + -- ';;t', + -- 'Telescope', + -- desc = 'telescope: select (interactive)', + -- }, + { + mode = 'n', + ';;f', + function() + local dir + if vim.opt.filetype:get() == 'oil' then + dir = require('oil').get_current_dir() + else + dir = vim.fn.expand('%:p:h') + end + -- require('fzf-lua').files({ cwd = dir }) + _G.feedkeys(':Fzf files cwd=' .. dir) + end, + desc = 'fzf: files (interactive)', + }, + { + mode = 'n', + ';;g', + function() + local dir + if vim.opt.filetype:get() == 'oil' then + dir = require('oil').get_current_dir() + else + dir = vim.fn.expand('%:p:h') + end + _G.feedkeys(':Fzf live_grep cwd=' .. dir) + end, + desc = 'fzf: grep (interactive)', + }, + }, + }, +} diff --git a/.config/nvim/lua/plugins/gentoo.lua b/.config/nvim/lua/plugins/gentoo.lua new file mode 100644 index 0000000..470e6de --- /dev/null +++ b/.config/nvim/lua/plugins/gentoo.lua @@ -0,0 +1,15 @@ +return { + { + 'gentoo/gentoo-syntax', + -- ft = { 'ebuild' }, + -- init = function() + -- vim.api.nvim_create_autocmd('LspAttach', { + -- callback = function(args) + -- if vim.opt.filetype == 'ebuild' then + -- vim.lsp.stop_client(vim.lsp.get_clients({ bufnr = args.bufnr })) + -- end + -- end, + -- }) + -- end, + }, +} diff --git a/.config/nvim/lua/plugins/git.lua b/.config/nvim/lua/plugins/git.lua new file mode 100644 index 0000000..2561ad9 --- /dev/null +++ b/.config/nvim/lua/plugins/git.lua @@ -0,0 +1,116 @@ +return { + { + 'lewis6991/gitsigns.nvim', + lazy = false, + opts = { + debug_mode = false, + }, + keys = { + { + ']c', + function() + if vim.wo.diff then + vim.cmd.normal({ ']c', bang = true }) + else + require('gitsigns').nav_hunk('next') + end + end, + desc = 'Gitsigns: next hunk', + }, + { + '[c', + function() + if vim.wo.diff then + vim.cmd.normal({ '[c', bang = true }) + else + require('gitsigns').nav_hunk('prev') + end + end, + desc = 'Gitsigns: prev hunk', + }, + { 'g', '', desc = 'git' }, + { 'g', 'Gitsigns', desc = 'Gitsigns: select action' }, + { 'gb', 'Gitsigns blame', desc = 'Gitsigns: blame' }, + { 'ga', 'Gitsigns stage_hunk', desc = 'Gitsigns: stage hunk' }, + { 'ga', ':Gitsigns stage_hunk', desc = 'Gitsigns: stage hunk', mode = 'x' }, + { 'gd', ':Gitsigns diffthis', desc = 'Gitsigns: diff' }, + { + ';c', + function() + require('gitsigns').setqflist('all', { open = false }) + require('fzf-lua').quickfix({ prompt = 'Git changesets' }) + end, + desc = 'Gitsigns: list hunks', + }, + }, + }, + + { + 'linrongbin16/gitlinker.nvim', + cmd = { 'GitLink' }, + dependencies = { 'nvim-lua/plenary.nvim' }, + opts = { + message = true, + }, + keys = { + { + 'gl', + vim.cmd.GitLink, + desc = 'GitLinker: clipboard', + }, + }, + }, + + { + 'moyiz/git-dev.nvim', + lazy = true, + cmd = { 'GitDevOpen', 'GitDevCleanAll' }, + opts = { + read_only = false, + }, + }, + + { + 'isakbm/gitgraph.nvim', + dependencies = { 'sindrets/diffview.nvim' }, + opts = { + symbols = { + merge_commit = 'M', + commit = '∙', + }, + format = { + timestamp = '%d-%m-%Y %H:%M:%S %z', + fields = { 'hash', 'timestamp', 'author', 'branch_name', 'tag' }, + }, + }, + init = vim.schedule_wrap(function() + vim.api.nvim_set_hl(0, 'GitGraphBranch1', { fg = 'NvimLightGray1' }) + vim.api.nvim_set_hl(0, 'GitGraphBranch2', { fg = 'NvimLightMagenta' }) + vim.api.nvim_set_hl(0, 'GitGraphBranch3', { fg = 'NvimLightRed' }) + vim.api.nvim_set_hl(0, 'GitGraphBranch4', { fg = 'NvimDarkCyan' }) + vim.api.nvim_set_hl(0, 'GitGraphBranch5', { fg = 'NvimDarkYellow' }) + vim.api.nvim_set_hl(0, 'GitGraphHash', { fg = 'NvimLightMagenta' }) + vim.api.nvim_set_hl(0, 'GitGraphAuthor', { fg = 'NvimLightGray4', italic = true }) + vim.api.nvim_set_hl(0, 'GitGraphTimestamp', { fg = 'NvimLightCyan' }) + vim.api.nvim_set_hl(0, 'GitGraphBranchName', { fg = 'NvimLightYellow' }) + vim.api.nvim_set_hl(0, 'GitGraphBranchTag', { fg = 'NvimLightYellow' }) + vim.api.nvim_set_hl(0, 'GitGraphBranchMsg', { link = 'Normal' }) + -- vim.api.nvim_create_autocmd('FileType', { + -- pattern = { 'gitgraph' }, + -- callback = function() + -- vim.keymap.set('n', 'q', 'bdel!', { silent = true, buffer = 0 }) + -- end, + -- group = vim.api.nvim_create_augroup('GitGraph'), + -- }) + end), + keys = { + { + 'g-', + function() + require('gitgraph').draw({}, { all = true, max_count = 5000 }) + end, + desc = 'GitGraph: view log', + }, + }, + }, +} diff --git a/.config/nvim/lua/plugins/icons.lua b/.config/nvim/lua/plugins/icons.lua new file mode 100644 index 0000000..9a597ab --- /dev/null +++ b/.config/nvim/lua/plugins/icons.lua @@ -0,0 +1,13 @@ +return { + { + 'echasnovski/mini.icons', + version = false, + events = { 'VeryLazy' }, + -- opts = {}, + config = function(_, opts) + require('mini.icons').setup(opts) + ---@diagnostic disable-next-line: undefined-global + MiniIcons.mock_nvim_web_devicons() + end, + }, +} diff --git a/.config/nvim/lua/plugins/indent.lua b/.config/nvim/lua/plugins/indent.lua new file mode 100644 index 0000000..e247c5a --- /dev/null +++ b/.config/nvim/lua/plugins/indent.lua @@ -0,0 +1,30 @@ +return { + -- show indents using virtual text + { + 'lukas-reineke/indent-blankline.nvim', + lazy = false, + main = 'ibl', + opts = { + indent = { + char = '▏', + }, + scope = { + enabled = true, + show_start = false, + show_end = false, + char = '▌', + }, + }, + }, + -- detect indent from the buffer contents + { + enabled = false, + 'NMAC427/guess-indent.nvim', + lazy = false, + opts = { + auto_cmd = true, + filetype_exclude = { 'netrw', 'tutor', 'dirbuf', 'nvimtree', 'oil' }, + buftype_exclude = { 'help', 'nofile', 'terminal', 'prompt' }, + }, + }, +} diff --git a/.config/nvim/lua/plugins/lsp.lua b/.config/nvim/lua/plugins/lsp.lua new file mode 100644 index 0000000..aebf3c4 --- /dev/null +++ b/.config/nvim/lua/plugins/lsp.lua @@ -0,0 +1,6 @@ +return { + { + 'neovim/nvim-lspconfig', + version = '^2.0', + } +} diff --git a/.config/nvim/lua/plugins/markdown.lua b/.config/nvim/lua/plugins/markdown.lua new file mode 100644 index 0000000..b21255e --- /dev/null +++ b/.config/nvim/lua/plugins/markdown.lua @@ -0,0 +1,82 @@ +return { + { + -- handy markdown commands + 'tadmccorkle/markdown.nvim', + ft = { 'markdown' }, + opts = { + mappings = false, + on_attach = function(buf) + local set = function(mode, lhs, rhs, desc) + vim.keymap.set(mode, lhs, rhs, { buffer = buf, desc = 'Markdown: ' .. desc }) + end + set('n', 'nio', 'MDListItemBelow', 'Insert list item below') + set('n', 'niO', 'MDListItemAbove', 'Insert list item above') + set({ 'n', 'v', 'x', 'i' }, '', 'MDTaskToggle', 'Toggle task') + set('x', '', 'gv(markdown_add_link_visual)', 'Make link') + end, + }, + }, + { + -- pretty markdown + 'MeanderingProgrammer/markdown.nvim', + name = 'render-markdown', -- needed if used together with markdown.nvim above + main = 'render-markdown', + dependencies = { + 'nvim-treesitter/nvim-treesitter', + 'echasnovski/mini.icons', + }, + ft = { 'markdown' }, + opts = { + completions = { blink = { enabled = true } }, + sign = { enabled = true }, + indent = { enabled = false }, + heading = { + width = 'block', + icons = { + '▒ ', + '▒▒ ', + '▒▒▒ ', + '▒▒▒▒ ', + '▒▒▒▒▒ ', + '▒▒▒▒▒▒ ', + }, + signs = { 'ⅰ', 'ⅱ', 'ⅲ', 'ⅳ', 'ⅴ', 'ⅵ' }, + backgrounds = {}, + foregrounds = {}, + }, + bullet = { + icons = { '* ', '-', '>' }, + }, + checkbox = { + checked = { icon = ' 󰄲 ' }, + unchecked = { icon = ' 󰄱 ' }, + custom = { + todo = { raw = '[-]', rendered = ' 󰔟 ', highlight = 'RenderMarkdownTodo' }, + }, + }, + code = { + width = 'block', + border = 'thin', + disable_background = true, + }, + }, + init = vim.schedule_wrap(function() + local hl = vim.api.nvim_set_hl + hl(0, '@markup.bold', { link = 'markdownBold', force = true }) + hl(0, '@markup.italic', { link = 'markdownItalic', force = true }) + + -- hl(0, 'RenderMarkdownH1', { fg = 'NvimLightCyan' }) + -- hl(0, 'RenderMarkdownH1Bg', { bg = 'NvimDarkCyan' }) + -- hl(0, 'RenderMarkdownH2', { fg = 'NvimLightMagenta' }) + -- hl(0, 'RenderMarkdownH2Bg', { bg = 'NvimDarkMagenta' }) + -- hl(0, 'RenderMarkdownH3', { fg = 'NvimLightYellow' }) + -- hl(0, 'RenderMarkdownH3Bg', { bg = 'NvimDarkYellow' }) + -- hl(0, 'RenderMarkdownH4', { fg = 'NvimLightBlue' }) + -- hl(0, 'RenderMarkdownH4Bg', { bg = 'NvimDarkBlue' }) + -- hl(0, 'RenderMarkdownH5', { fg = 'NvimLightRed' }) + -- hl(0, 'RenderMarkdownH5Bg', { bg = 'NvimDarkRed' }) + + hl(0, 'RenderMarkdownBullet', { link = '@markup.list', force = true }) + end), + }, +} diff --git a/.config/nvim/lua/plugins/mini.lua b/.config/nvim/lua/plugins/mini.lua new file mode 100644 index 0000000..fb4c9a6 --- /dev/null +++ b/.config/nvim/lua/plugins/mini.lua @@ -0,0 +1,26 @@ +return { + { + 'echasnovski/mini.align', + version = false, + lazy = false, + opts = {}, + }, + { + 'echasnovski/mini.ai', + version = false, + lazy = false, + opts = {}, + }, + { + 'echasnovski/mini.surround', + version = false, + lazy = false, + opts = {}, + }, + { + 'echasnovski/mini.operators', + version = false, + lazy = false, + opts = {}, + }, +} diff --git a/.config/nvim/lua/plugins/oil.lua b/.config/nvim/lua/plugins/oil.lua new file mode 100644 index 0000000..401fe8b --- /dev/null +++ b/.config/nvim/lua/plugins/oil.lua @@ -0,0 +1,21 @@ +return { + { + 'stevearc/oil.nvim', + lazy = false, + opts = { + keymaps = { + ['gt'] = { + function() + local cwd = require('oil').get_current_dir() + vim.cmd('silent !footclient --no-wait -D ' .. cwd) + end, + nowait = true, + desc = 'Open current directory with foot', + }, + }, + }, + keys = { + { mode = 'n', '-', 'Oil', desc = 'oil: open parent directory' }, + }, + }, +} diff --git a/.config/nvim/lua/plugins/snippets.lua b/.config/nvim/lua/plugins/snippets.lua new file mode 100644 index 0000000..97a4455 --- /dev/null +++ b/.config/nvim/lua/plugins/snippets.lua @@ -0,0 +1,13 @@ +return { + { + 'L3MON4D3/LuaSnip', + version = 'v2.*', + build = 'make install_jsregexp', + config = function() + require('config.snippets') + end, + dependencies = { + "rafamadriz/friendly-snippets", + }, + } +} diff --git a/.config/nvim/lua/plugins/treesitter.lua b/.config/nvim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..93f396d --- /dev/null +++ b/.config/nvim/lua/plugins/treesitter.lua @@ -0,0 +1,93 @@ +return { + { + 'nvim-treesitter/nvim-treesitter', + branch = 'master', + dependencies = { + { 'nvim-treesitter/nvim-treesitter-refactor', lazy = false }, + { 'nvim-treesitter/nvim-treesitter-textobjects', lazy = false }, + -- { 'nvim-treesitter/playground', cmd = { 'TSPlayground' } }, + }, + lazy = false, + build = ':TSUpdate', + config = function(_, opts) + require('nvim-treesitter.configs').setup(opts) + + -- use bash parser for gentoo ebuilds + vim.treesitter.language.register('bash', 'ebuild') + end, + opts = { + ensure_installed = { + 'bash', + 'c', + 'cmake', + 'comment', + 'cpp', + 'css', + 'dockerfile', + 'go', + 'gomod', + 'gotmpl', + 'gowork', + 'html', + 'javascript', + 'json', + 'jsonc', + 'lua', + 'make', + 'markdown', + 'markdown_inline', + 'ninja', + 'python', + 'regex', + 'rust', + 'scss', + 'sql', + 'todotxt', + 'toml', + 'typescript', + 'typst', + 'vim', + 'vimdoc', + 'yaml', + 'zig', + }, + highlight = { + enable = true, + additional_vim_regex_highlighting = { 'markdown' }, + }, + indent = { + enable = true, + }, + refactor = { + navigation = { + enable = true, + }, + smart_rename = { + enable = true, + }, + }, + textobjects = { + select = { + enable = true, + keymaps = { + ['ib'] = '@block.inner', + ['ab'] = '@block.outer', + -- ['ic'] = '@conditional.inner', + -- ['ac'] = '@conditional.outer', + ['if'] = '@function.inner', + ['af'] = '@function.outer', + ['il'] = '@loop.inner', + ['al'] = '@loop.outer', + ['is'] = '@scopename.inner', + ['as'] = '@scopename.outer', + ['ic'] = '@comment.inner', + ['ac'] = '@comment.outer', + }, + selection_mode = { + ['@comment.outer'] = 'V', + }, + }, + }, + }, + }, +} diff --git a/.config/nvim/lua/plugins/whichkey.lua b/.config/nvim/lua/plugins/whichkey.lua new file mode 100644 index 0000000..dc21eda --- /dev/null +++ b/.config/nvim/lua/plugins/whichkey.lua @@ -0,0 +1,10 @@ +return { + { + 'folke/which-key.nvim', + event = 'VeryLazy', + opts = { + sort = { 'alphanum' }, + icons = { separator = '→ ', group = '🞱 ' }, + }, + }, +} -- cgit 1.4.1