local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not (vim.uv or 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) require("lazy").setup({ -- Auto-completion engine { "hrsh7th/nvim-cmp", dependencies = { "hrsh7th/cmp-nvim-lsp", -- lsp auto-completion "hrsh7th/cmp-buffer", -- buffer auto-completion "hrsh7th/cmp-path", -- path auto-completion "hrsh7th/cmp-cmdline", -- cmdline auto-completion "saadparwaiz1/cmp_luasnip", -- luasnip auto-completion }, config = function() require("config.nvim-cmp") end, }, -- Code snippet engine { "L3MON4D3/LuaSnip", version = "v2.*", config = function() require("luasnip.loaders.from_snipmate").lazy_load() require("luasnip.loaders.from_lua").lazy_load() end, }, -- -- LSP manager and others -- "williamboman/mason.nvim", "williamboman/mason-lspconfig.nvim", "neovim/nvim-lspconfig", -- Nice plugin to show what LSPs are doing in the background (and others -- using $/progress and vim.notify()) { "j-hui/fidget.nvim", opts = { -- options }, }, -- show lsp signature while coding { "ray-x/lsp_signature.nvim", event = "VeryLazy", opts = { bind = true, floating_window = false, }, }, -- neogit setup { "NeogitOrg/neogit", dependencies = { "nvim-lua/plenary.nvim", -- required "sindrets/diffview.nvim", -- optional - Diff integration -- Only one of these is needed, not both. -- "nvim-telescope/telescope.nvim", -- optional "ibhagwan/fzf-lua", -- optional }, config = true }, -- org-mode { 'nvim-orgmode/orgmode', event = 'VeryLazy', ft = { 'org' }, config = function() -- Setup orgmode require('orgmode').setup({ mappings = { org = { org_move_subtree_up = { 'oK', '' }, org_move_subtree_down = { 'oJ', '' }, } }, -- org_agenda_files = '~/orgfiles/**/*', -- org_default_notes_file = '~/orgfiles/refile.org', org_agenda_files = '~/Documents/Eigene (Briefe etc.)/org/*.org', org_default_notes_file = '~/Documents/Eigene (Briefe etc.)/org/refile.org', org_todo_keywords = { 'TODO(t)', 'STARTED(s)', 'PLANNED(p)', '|', 'DONE(d)', 'UNPLANNED(u)' }, org_custom_exports = { f = { label = 'Export to HTML format', action = function(exporter) local current_file = vim.api.nvim_buf_get_name(0) local target = vim.fn.fnamemodify(current_file, ':p:r') .. '.html' local command = { 'pandoc', '--filter', 'pandoc-plot', current_file, '--standalone', '--toc', '--number-sections', '--output', target } local on_success = function(output) print('Success!') vim.api.nvim_echo({ { table.concat(output, '\n') } }, true, {}) end local on_error = function(err) print('Error!') vim.api.nvim_echo({ { table.concat(err, '\n'), 'ErrorMsg' } }, true, {}) end return exporter(command, target, on_success, on_error) end } }, }) -- NOTE: If you are using nvim-treesitter with ~ensure_installed = "all"~ option -- add ~org~ to ignore_install -- require('nvim-treesitter.configs').setup({ -- ensure_installed = 'all', -- ignore_install = { 'org' }, -- }) end, }, -- org-roam - lets try it out (2025-05-20) { "chipsenkbeil/org-roam.nvim", config = function() require("org-roam").setup({ directory = "~/Documents/Eigene (Briefe etc.)/org/roam", -- optional -- org_files = { -- "~/another_org_dir", -- "~/some/folder/*.org", -- "~/a/single/org_file.org", -- } bindings = { prefix = "r" } }) end }, -- comfortable table editing, esp. used in orgmode { 'dhruvasagar/vim-table-mode' }, -- fzf-lua { "ibhagwan/fzf-lua", -- optional for icon support dependencies = { "nvim-tree/nvim-web-devicons" }, config = function() -- calling `setup` is optional for customization local fzf = require("fzf-lua") fzf.setup({ "default-title" }) fzf.register_ui_select() end }, -- which-key { "folke/which-key.nvim", event = "VeryLazy", opts = { -- your configuration comes here -- or leave it empty to use the default settings -- refer to the configuration section below -- preset = 'helix', -- preset = 'classic', -- preset = 'modern', preset = false, expand = 3, keys = { scroll_down = "", -- binding to scroll down inside the popup scroll_up = "", -- binding to scroll up inside the popup }, plugins = { presets = { motions = true, g = true, } }, win = { -- no_overlap = false, height = { min = 4 }, -- height = { min = 4, max = math.huge }, width = { min = 25, max = 120 }, -- title = true, -- title_pos = "center", -- border = "rounded", col = -1, row = -1, padding = { 1, 3 }, }, layout = { spacing = 2, -- width = { min = math.huge }, width = { min = 20 }, }, }, keys = { { "?", function() require("which-key").show({ global = true }) end, desc = "Buffer Local Keymaps (which-key)", }, }, dependencies = { "echasnovski/mini.icons" }, }, -- treesitter { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate", config = function() local configs = require("nvim-treesitter.configs") configs.setup({ ensure_installed = { "c", "lua", "vim", "vimdoc", "query", "elixir", "heex", "javascript", "html", "diff", "go", "rust", "python" }, sync_install = false, highlight = { enable = true }, indent = { enable = true }, }) end }, -- lualine statusline plugin { 'nvim-lualine/lualine.nvim', dependencies = { 'nvim-tree/nvim-web-devicons' }, config = function() -- an alternative might be: -- https://github.com/nvim-treesitter/nvim-treesitter-context local function breadcrumb() local result = require 'nvim-treesitter'.statusline( { type_patterns = { "class", "impl", "function", "method", "import", "for", "if", "while", "variable", "comment", }, separator = " ▶ " } ) if result == "" then result = ' ' elseif result == nil then result = '' end return result end require("lualine").setup { options = { icons_enabled = false, theme = 'papercolor_light', component_separators = {}, section_separators = {}, disabled_filetypes = { statusline = {}, winbar = { "neo-tree" }, }, ignore_focus = {}, always_divide_middle = true, globalstatus = false, refresh = { statusline = 1000, tabline = 1000, winbar = 1000, } }, sections = { lualine_a = { { 'filename', path = 1, shorting_target = 50 } }, lualine_b = { 'branch', 'diff', 'diagnostics' }, lualine_c = {}, lualine_x = { 'encoding', 'fileformat', 'filetype' }, lualine_y = { 'filesize' }, lualine_z = { 'progress', 'location' } }, inactive_sections = { lualine_a = { { 'filename', path = 1, shorting_target = 50 } }, lualine_b = {}, lualine_c = {}, -- lualine_x = { 'encoding', 'fileformat', 'filetype' }, lualine_x = {}, lualine_y = { 'filesize' }, lualine_z = { 'location' } }, tabline = {}, winbar = { lualine_a = { { breadcrumb, color = { bg = '#2a2a2a', fg = '#cfcfcf' }, }, }, }, inactive_winbar = { lualine_a = { { breadcrumb, color = { bg = '#101010', fg = '#999999' }, draw_empty = true } }, }, extensions = {} } end }, -- neo-tree file management { "nvim-neo-tree/neo-tree.nvim", branch = "v3.x", dependencies = { "nvim-lua/plenary.nvim", "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended "MunifTanjim/nui.nvim", -- "3rd/image.nvim", -- Optional image support in preview window: See `# Preview Mode` for more information }, config = function() require("neo-tree").setup({ window = { position = "left", mappings = { [""] = { "toggle_node", nowait = false, -- disable `nowait` if you have existing combos starting with this char that you want to use }, } } }) end }, { "antosha417/nvim-lsp-file-operations", dependencies = { "nvim-lua/plenary.nvim", "nvim-neo-tree/neo-tree.nvim", }, config = function() require("lsp-file-operations").setup() end, }, -- workspaces, lightweight "projects" { "natecraddock/workspaces.nvim", config = function() require("workspaces").setup { -- sort the list of workspaces by name after loading from the workspaces path. sort = true, -- sort by recent use rather than by name. requires sort to be true mru_sort = false, -- option to automatically activate workspace when opening neovim in a workspace directory auto_open = false, -- option to automatically activate workspace when changing directory not via this plugin auto_dir = true, hooks = { open = "FzfLua files" } } end }, -- calculate using qalc cli, call :QalcAttach or :Qalc { "Apeiros-46B/qalc.nvim", config = function() require('qalc').setup({ bufname = "Qalculate", }) end, }, -- TODO, WARN, HACK, PERF, NOTE, TEST and others highlighting and searching { "folke/todo-comments.nvim", dependencies = { "nvim-lua/plenary.nvim" }, opts = { -- your configuration comes here -- or leave it empty to use the default settings -- refer to the configuration section below } }, -- highlight word under cursor { "dwrdx/mywords.nvim", }, -- Calendar view { "itchyny/calendar.vim" }, -- treesitter asciidoc support -- // NOTE.2025-01-17 seems to be broken -- { "cpkio/nvim-treesitter-asciidoc" }, -- Greeter to run on NeoVim startup { 'goolord/alpha-nvim', dependencies = { 'nvim-tree/nvim-web-devicons', }, config = function() local alpha = require 'alpha' local dashboard = require 'alpha.themes.dashboard' _Gopts = { position = 'center', hl = 'Type', wrap = 'overflow', } -- DASHBOARD HEADER local function getGreeting() local tableTime = os.date '*t' local datetime = os.date ' %Y-%m-%d-%A  %H:%M:%S ' local hour = tableTime.hour local greetingsTable = { [1] = ' Sleep well', [2] = ' Good morning', [3] = ' Good afternoon', [4] = ' Good evening', [5] = '󰖔 Good night', } local greetingIndex = 0 if hour == 23 or hour < 7 then greetingIndex = 1 elseif hour < 12 then greetingIndex = 2 elseif hour >= 12 and hour < 18 then greetingIndex = 3 elseif hour >= 18 and hour < 21 then greetingIndex = 4 elseif hour >= 21 then greetingIndex = 5 end return datetime .. ' ' .. greetingsTable[greetingIndex] end local logo = [[  ████ ██████ █████ ██ ███████████ █████  █████████ ███████████████████ ███ ███████████ █████████ ███ █████████████ █████ ██████████████ █████████ ██████████ █████████ █████ █████ ████ █████ ███████████ ███ ███ █████████ █████ █████ ████ █████ ██████ █████████████████████ ████ █████ █████ ████ ██████ ]] local greeting = getGreeting() local marginBottom = 0 -- Split logo into lines local logoWidth = 0 for line in logo:gmatch '[^\n]+' do logoWidth = math.max(logoWidth, #line / 2) end logoWidth = 75 -- code above does not work with utf8 strings in lua 5.1 -- Calculate padding for centering the greeting local greetingWidth = #greeting - 3 local padding = math.floor((logoWidth - greetingWidth) / 2) -- Generate spaces for padding local paddedGreeting = string.rep(' ', padding) .. greeting local userName = "You work as '" .. vim.env.USER .. "'." -- Calculate padding for centering the username local userNameWidth = #userName local padding = math.floor((logoWidth - userNameWidth) / 2) -- Generate spaces for padding local userNamePadded = string.rep(' ', padding) .. userName -- Add margin lines below the padded greeting local margin = string.rep('\n', marginBottom * 5) -- Concatenate logo, padded greeting, and margin local adjustedLogo = logo .. '\n' .. paddedGreeting .. '\n\n' .. userNamePadded .. '\n' .. margin dashboard.section.header.val = vim.split(adjustedLogo, '\n') dashboard.section.buttons.val = { dashboard.button('o', '󱙺 AI Chat', 'OGPT'), dashboard.button('n', ' New file', ':ene startinsert '), dashboard.button('s', ' Settings', 'WorkspacesOpen config-nvim'), dashboard.button('u', '󱐥 Update plugins', 'Lazy update'), dashboard.button('w', ' Workspaces', 'WorkspacesOpen'), dashboard.button('q', '󰤆 Quit', 'qa'), } -- dashboard.section.footer.val = greeting vim.api.nvim_create_autocmd('User', { pattern = 'LazyVimStarted', desc = 'Add Alpha dashboard footer', once = true, callback = function() local stats = require('lazy').stats() local ms = math.floor(stats.startuptime * 100 + 0.5) / 100 dashboard.section.footer.val = { ' ', ' ', ' ', ' Loaded ' .. stats.count .. ' plugins  in ' .. ms .. ' ms ' } dashboard.section.header.opts.hl = 'DashboardFooter' pcall(vim.cmd.AlphaRedraw) end, }) dashboard.opts.opts.noautocmd = true alpha.setup(dashboard.opts) end, }, -- improved Rust support { 'mrcjkb/rustaceanvim', version = '^6', -- Recommended lazy = false, -- This plugin is already lazy }, -- show git changes on the left { "lewis6991/gitsigns.nvim", config = function() require('gitsigns').setup() end, }, -- Live Coding: sonic-pi music programming { 'magicmonty/sonicpi.nvim', config = function() require('sonicpi').setup({ -- server_dir = '/opt/sonic-pi/app/server', lsp_diagnostics = true, mappings = { { 'n', 'd', ':SonicPiStartDaemon', { desc = 'Sonic Pi: start daemon' } }, { 'n', 's', require('sonicpi.remote').stop, { desc = 'Sonic Pi: stop' } }, { 'i', '', require('sonicpi.remote').stop, { desc = 'Sonic Pi: stop' } }, { 'n', 'r', require('sonicpi.remote').run_current_buffer, { desc = 'Sonic Pi: run' } }, { 'i', '', require('sonicpi.remote').run_current_buffer, { desc = 'Sonic Pi: run' } }, { 'n', 'R', ':SonicPiSendBuffer', { desc = 'Sonic Pi: send buffer' } }, { 'i', '', ':SonicPiSendBuffer', { desc = 'Sonic Pi: send buffer' } }, { 'v', 's', require('sonicpi.remote').stop, { desc = 'Sonic Pi: stop' } }, { 'v', 'v', function() require('sonicpi.remote').run_code(SL_get_visual_selection()) end, { desc = 'Sonic Pi: send visual range' } } }, single_file = true, }) end, dependencies = { 'hrsh7th/nvim-cmp', 'kyazdani42/nvim-web-devicons' }, }, -- easy term on a shortcut { "akinsho/toggleterm.nvim", config = true, keys = { { "", ":ToggleTerm", desc = "Toggle terminal", }, { "", ":ToggleTerm", mode = 't', desc = "Toggle terminal", }, }, }, -- Live Coding: tidal cycles support { 'tidalcycles/vim-tidal', config = function() vim.g.tidal_sc_enable = 1 end, }, -- debugging support, needed for things like rustaceanvim { 'mfussenegger/nvim-dap' }, -- show indent markers { "lukas-reineke/indent-blankline.nvim", main = "ibl", ---@module "ibl" ---@type ibl.config opts = {}, }, -- ollama and LLM integration { { "huynle/ogpt.nvim", event = "VeryLazy", opts = { default_provider = "ollama", edgy = true, -- enable this! single_window = false, -- set this to true if you want only one OGPT window to appear at a time providers = { ollama = { api_host = os.getenv("OLLAMA_API_HOST") or "http://localhost:11434", api_key = os.getenv("OLLAMA_API_KEY") or "", model = "llama3.2-vision:sl", } } }, dependencies = { "MunifTanjim/nui.nvim", "nvim-lua/plenary.nvim", "nvim-telescope/telescope.nvim" } }, { "folke/edgy.nvim", event = "VeryLazy", init = function() vim.opt.laststatus = 3 vim.opt.splitkeep = "screen" -- or "topline" or "screen" end, opts = { exit_when_last = false, animate = { enabled = false, }, wo = { winbar = true, winfixwidth = true, winfixheight = false, winhighlight = "WinBar:EdgyWinBar,Normal:EdgyNormal", spell = false, signcolumn = "no", }, keys = { -- -- close window ["q"] = function(win) win:close() end, -- close sidebar ["Q"] = function(win) win.view.edgebar:close() end, -- increase width [""] = function(win) win:resize("width", 3) end, -- decrease width [""] = function(win) win:resize("width", -3) end, -- increase height [""] = function(win) win:resize("height", 3) end, -- decrease height [""] = function(win) win:resize("height", -3) end, }, right = { { title = "OGPT Popup", ft = "ogpt-popup", size = { width = 0.2 }, wo = { wrap = true, }, }, { title = "OGPT Parameters", ft = "ogpt-parameters-window", size = { height = 6 }, wo = { wrap = true, }, }, { title = "OGPT Template", ft = "ogpt-template", size = { height = 6 }, }, { title = "OGPT Sessions", ft = "ogpt-sessions", size = { height = 6 }, wo = { wrap = true, }, }, { title = "OGPT System Input", ft = "ogpt-system-window", size = { height = 6 }, }, { title = "OGPT", ft = "ogpt-window", size = { height = 0.5 }, wo = { wrap = true, }, }, { title = "OGPT {{{selection}}}", ft = "ogpt-selection", size = { width = 80, height = 4 }, wo = { wrap = true, }, }, { title = "OGPt {{{instruction}}}", ft = "ogpt-instruction", size = { width = 80, height = 4 }, wo = { wrap = true, }, }, { title = "OGPT Chat", ft = "ogpt-input", size = { width = 80, height = 4 }, wo = { wrap = true, }, }, }, }, }, -- new plugins here }, })