diff --git a/nvim/.config/nvim/after/ftplugin/markdown.lua b/nvim/.config/nvim/after/ftplugin/markdown.lua index 7f2c06f..84ad5c0 100644 --- a/nvim/.config/nvim/after/ftplugin/markdown.lua +++ b/nvim/.config/nvim/after/ftplugin/markdown.lua @@ -35,9 +35,9 @@ if require("core.util").is_available("peek") then peek.open() end end - map("n", "pp", togglePeek, { desc = "show md preview" }) + map("n", "po", togglePeek, { desc = "show md preview" }) else - map("n", "pp", "MarkdownPreviewToggle", { desc = "show md preview" }) + map("n", "po", "MarkdownPreviewToggle", { desc = "show md preview" }) end -- create mindmaps directly from markdown! requires external executable diff --git a/nvim/.config/nvim/after/ftplugin/quarto.lua b/nvim/.config/nvim/after/ftplugin/quarto.lua index 18d1d03..8840c65 100644 --- a/nvim/.config/nvim/after/ftplugin/quarto.lua +++ b/nvim/.config/nvim/after/ftplugin/quarto.lua @@ -6,14 +6,13 @@ local default_buffer_session = function() if vim.fn.getftype(dir) ~= "dir" then vim.fn.mkdir(dir, "p") end - return temp_path end -- Start quarto session local startsession = function(file, args) file = file or default_buffer_session() - local path = require("core.util").get_python_venv() + local path = require("core.util").get_python_venv_bin() vim.g["python3_host_prog"] = path if vim.fn.executable("jupyter-console") ~= 1 then @@ -41,92 +40,27 @@ vim.api.nvim_create_user_command("JupyterStart", function() startsession() end, {}) -local map = vim.keymap.set - -local function molten_mappings_set() - -- Operate jupyter notebooks from within vim - map("n", "cc", ":MoltenEvaluateLine", { silent = true }) - map( - "n", - "C", - require("quarto.runner").run_cell, - { silent = true, desc = "Evaluate current code cell" } - ) - map("x", "c", ":MoltenEvaluateVisual", { silent = true }) - map( - "n", - "c", - "nvim_exec('MoltenEvaluateOperator', v:true)", - { expr = true, silent = true, desc = "+code-evaluation" } - ) - map("n", "cr", ":MoltenReevaluateCell", { silent = true }) - map("n", "cu", ":MoltenShowOutput", { silent = true }) - map("n", "cU", ":noautocmd :MoltenEnterOutput", { silent = true, desc = "Molten enter output" }) - map("n", "cd", ":MoltenDelete", { silent = true }) - map("n", "ci", ":MoltenInterrupt") - map("n", "cN", ":MoltenInit ") - map("n", "cD", ":MoltenDeinit") - map("n", "cR", ":MoltenRestart") - map("n", "cA", require("quarto.runner").run_all, { silent = true, desc = "Evaluate all code cells" }) - map( - "n", - "ca", - require("quarto.runner").run_above, - { silent = true, desc = "Evaluate cells above current" } - ) - map( - "n", - "cb", - require("quarto.runner").run_below, - { silent = true, desc = "Evaluate cells below current" } - ) - - -- jump to beginning of previous/ next cell code - map("n", "]c", "/^```{}:nohl", { desc = "Next quarto cell" }) - map("n", "[c", "?^```n}:nohl", { desc = "Previous quarto cell" }) - -- insert cell header above/below - map("n", "co", "o```{python}```k", { desc = "Insert quarto cell below" }) - map("n", "cO", "O```{python}```k", { desc = "Insert quarto cell above" }) -end - -vim.api.nvim_create_autocmd("User", { - pattern = "MoltenInitPost", - callback = molten_mappings_set, +vim.api.nvim_create_autocmd({"InsertEnter", "BufEnter"}, { + callback = function() + if vim.b["sessionfile"] == nil then + local path = default_buffer_session() + vim.b["sessionfile"] = path + vim.schedule_wrap(startsession(path)) + end + end, }) -local bufnr = 0 -map("n", "[d", "lua vim.diagnostic.goto_prev()", { buffer = bufnr, desc = "Previous diagnostic" }) -map("n", "]d", "lua vim.diagnostic.goto_next()", { buffer = bufnr, desc = "Next diagnostic" }) -map( - "n", - "[e", - "lua vim.diagnostic.goto_prev({severity = vim.diagnostic.severity.ERROR})", - { buffer = bufnr, desc = "Previous error" } -) -map( - "n", - "]e", - "lua vim.diagnostic.goto_next({severity = vim.diagnostic.severity.ERROR})", - { buffer = bufnr, desc = "Next error" } -) +-- -- -- TODO find better way to enable lsp key mappings for quarto buffers +-- -- local prefix = require("which-key").register +-- -- prefix({ ["l"] = { name = "+lsp" } }) +-- -- map("n", "li", "LspInfo", { buffer = bufnr, desc = "Lsp Info" }) +-- -- map("n", "ld", "lua vim.diagnostic.open_float()", { buffer = bufnr, desc = "Line diagnostics" }) +-- -- map("n", "la", "lua vim.lsp.buf.code_action()", { buffer = bufnr, desc = "Codeactions" }) +-- -- map("n", "ln", "lua vim.lsp.buf.rename()", { buffer = bufnr, desc = "Rename element" }) +-- -- map("n", "lr", "lua vim.lsp.buf.references()", { buffer = bufnr, desc = "References" }) +-- -- +-- -- map("n", "gD", "lua vim.lsp.buf.declaration()", { buffer = bufnr, desc = "Declaration" }) +-- -- map("n", "gs", "lua vim.lsp.buf.signature_help()", { buffer = bufnr, desc = "Signature help" }) +-- -- map("n", "gI", "lua vim.lsp.buf.implementation()", { buffer = bufnr, desc = "Implementation" }) +-- -- map("n", "gt", "lua vim.lsp.buf.type_definition()", { buffer = bufnr, desc = "Type definition" }) --- TODO find better way to enable lsp key mappings for quarto buffers -local prefix = require("which-key").register -prefix({ ["l"] = { name = "+lsp" } }) -map("n", "li", "LspInfo", { buffer = bufnr, desc = "Lsp Info" }) -map("n", "ld", "lua vim.diagnostic.open_float()", { buffer = bufnr, desc = "Line diagnostics" }) -map("n", "la", "lua vim.lsp.buf.code_action()", { buffer = bufnr, desc = "Codeactions" }) -map("n", "ln", "lua vim.lsp.buf.rename()", { buffer = bufnr, desc = "Rename element" }) -map("n", "lr", "lua vim.lsp.buf.references()", { buffer = bufnr, desc = "References" }) - -map("n", "K", "lua vim.lsp.buf.hover()", { buffer = bufnr, desc = "Hover definition" }) -map("n", "gd", "lua vim.lsp.buf.definition()", { buffer = bufnr, desc = "Definition" }) -map("n", "gD", "lua vim.lsp.buf.declaration()", { buffer = bufnr, desc = "Declaration" }) -map("n", "gs", "lua vim.lsp.buf.signature_help()", { buffer = bufnr, desc = "Signature help" }) -map("n", "gI", "lua vim.lsp.buf.implementation()", { buffer = bufnr, desc = "Implementation" }) -map("n", "gt", "lua vim.lsp.buf.type_definition()", { buffer = bufnr, desc = "Type definition" }) - -if vim.b["sessionfile"] == nil then - local path = default_buffer_session() - vim.b["sessionfile"] = path - vim.schedule_wrap(startsession(path)) -end +-- vim.g["python3_host_prog"] = vim.fn.expand(require("core.util").get_python_venv()) diff --git a/nvim/.config/nvim/lazy-lock.json b/nvim/.config/nvim/lazy-lock.json index 940af3f..3ed8b73 100644 --- a/nvim/.config/nvim/lazy-lock.json +++ b/nvim/.config/nvim/lazy-lock.json @@ -28,22 +28,26 @@ "dressing.nvim": { "branch": "master", "commit": "572314728cb1ce012e825fd66331f52c94acac12" }, "fidget.nvim": { "branch": "main", "commit": "ef99df04a1c53a453602421bc0f756997edc8289" }, "flash.nvim": { "branch": "main", "commit": "7bb4a9c75d1e20cd24185afedeaa11681829ba23" }, - "friendly-snippets": { "branch": "main", "commit": "700c4a25caacbb4648c9a27972c2fe203948e0c2" }, + "friendly-snippets": { "branch": "main", "commit": "682157939e57bd6a2c86277dfd4d6fbfce63dbac" }, "fwatch.nvim": { "branch": "main", "commit": "a691f7349dc66285cd75a1a698dd28bca45f2bf8" }, "git-conflict.nvim": { "branch": "main", "commit": "bfd9fe6fba9a161fc199771d85996236a0d0faad" }, - "gitsigns.nvim": { "branch": "main", "commit": "76927d14d3fbd4ba06ccb5246e79d93b5442c188" }, + "gitsigns.nvim": { "branch": "main", "commit": "0b04035bb7b3c83e999b9676e2fb46fd0aa9f910" }, "glance.nvim": { "branch": "master", "commit": "51059bcf21016387b6233c89eed220cf47fca752" }, "headlines.nvim": { "branch": "master", "commit": "618ef1b2502c565c82254ef7d5b04402194d9ce3" }, "image.nvim": { "branch": "master", "commit": "da64ce69598875c9af028afe129f916b02ccc42e" }, - "lazy.nvim": { "branch": "main", "commit": "fafe1f7c640aed75e70a10e6649612cd96f39149" }, + "img-clip.nvim": { "branch": "main", "commit": "fc30500c35663aa1762697f5aba31d43b86028f0" }, + "jupytext.nvim": { "branch": "main", "commit": "c8baf3ad344c59b3abd461ecc17fc16ec44d0f7b" }, + "lazy.nvim": { "branch": "main", "commit": "c501b429cf995c645454539b924aaefae45bb9eb" }, "lsp-setup.nvim": { "branch": "main", "commit": "6e4e977512ce426d8b52c27f3b6e6aefc73e1452" }, "lualine.nvim": { "branch": "master", "commit": "0a5a66803c7407767b799067986b4dc3036e1983" }, + "luarocks.nvim": { "branch": "main", "commit": "1db9093915eb16ba2473cfb8d343ace5ee04130a" }, "markmap.nvim": { "branch": "main", "commit": "5fb6755cf5434511cc23a4936c9eb76b9142fba5" }, + "mason-conform.nvim": { "branch": "main", "commit": "abce2be529f3b4b336c56d0ba6336a9144e0fee6" }, "mason-lspconfig.nvim": { "branch": "main", "commit": "9ae570e206360e47d30b4c35a4550c165f4ea7b7" }, - "mason-tool-installer.nvim": { "branch": "main", "commit": "c5e07b8ff54187716334d585db34282e46fa2932" }, + "mason-nvim-lint": { "branch": "main", "commit": "637a5b8f1b454753ec70289c4996d88a50808642" }, "mason.nvim": { "branch": "main", "commit": "c43eeb5614a09dc17c03a7fb49de2e05de203924" }, "mdeval.nvim": { "branch": "master", "commit": "2c32e2f3e7d8f222e7a4724989f218d036e1081d" }, - "mini.nvim": { "branch": "main", "commit": "f24747266a047617d06605a2316aa6c071662fa2" }, + "mini.nvim": { "branch": "main", "commit": "19e1584124cda35388d4fdb911eab7124014e541" }, "molten-nvim": { "branch": "main", "commit": "df5ccef3b6fda3582f7746e45327ee031f668826" }, "neogen": { "branch": "main", "commit": "0daffcec249bf42275e322361fe55b89a05ff278" }, "neotest": { "branch": "master", "commit": "f30bab1faef13d47f3905e065215c96a42d075ad" }, @@ -53,7 +57,7 @@ "nvim-colorizer.lua": { "branch": "master", "commit": "85855b38011114929f4058efc97af1059ab3e41d" }, "nvim-coverage": { "branch": "main", "commit": "aa4b4400588e2259e87e372b1e4e90ae13cf5a39" }, "nvim-lint": { "branch": "master", "commit": "941fa1220a61797a51f3af9ec6b7d74c8c7367ce" }, - "nvim-lspconfig": { "branch": "master", "commit": "4d38bece98300e3e5cd24a9aa0d0ebfea4951c16" }, + "nvim-lspconfig": { "branch": "master", "commit": "bd7c76375a511994c9ca8d69441f134dc10ae3bd" }, "nvim-nio": { "branch": "master", "commit": "7969e0a8ffabdf210edd7978ec954a47a737bbcc" }, "nvim-surround": { "branch": "main", "commit": "687ea2f33955df0042bf228853a82696265e7e2d" }, "nvim-toggleterm.lua": { "branch": "main", "commit": "066cccf48a43553a80a210eb3be89a15d789d6e6" }, @@ -69,21 +73,22 @@ "peek.nvim": { "branch": "master", "commit": "5820d937d5414baea5f586dc2a3d912a74636e5b" }, "plenary.nvim": { "branch": "master", "commit": "50012918b2fc8357b87cff2a7f7f0446e47da174" }, "popup.nvim": { "branch": "master", "commit": "b7404d35d5d3548a82149238289fa71f7f6de4ac" }, - "quarto-nvim": { "branch": "main", "commit": "67e09027b5d8bd948907734fc6fb15028ffdcd28" }, + "quarto-nvim": { "branch": "main", "commit": "a6e7452de5944f7f38a4b12f1d50e460c1dccd95" }, "rainbow-delimiters.nvim": { "branch": "master", "commit": "12b1a1e095d968887a17ef791c2edb78d7595d46" }, "smartcolumn.nvim": { "branch": "main", "commit": "d01b99355c7fab13233f48d0f28dc097e68a03f7" }, "stickybuf.nvim": { "branch": "master", "commit": "2160fcd536d81f5fa43f7167dba6634e814e3154" }, "telescope-fzf-native.nvim": { "branch": "main", "commit": "9ef21b2e6bb6ebeaf349a0781745549bbb870d27" }, + "telescope-luasnip.nvim": { "branch": "master", "commit": "11668478677de360dea45cf2b090d34f21b8ae07" }, "telescope.nvim": { "branch": "master", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }, - "trouble.nvim": { "branch": "main", "commit": "3609bb9a82bbab1ef95cf2c27ce7e52267a7d40d" }, + "trouble.nvim": { "branch": "main", "commit": "09380a8ed0694dbfbbcf59f9eaac499e259cb75c" }, "twilight.nvim": { "branch": "main", "commit": "8bb7fa7b918baab1ca81b977102ddb54afa63512" }, "undotree": { "branch": "main", "commit": "eab459ab87dd249617b5f7187bb69e614a083047" }, "vifm.vim": { "branch": "master", "commit": "a8130c37d144b51d84bee19f0532abcd3583383f" }, "vim-criticmarkup": { "branch": "master", "commit": "d15dc134eb177a170c79f6377f81eb02a9d20b02" }, "vim-numbertoggle": { "branch": "main", "commit": "df9b1fe616507340718716204ba7f434125bdf7a" }, "vim-pandoc-syntax": { "branch": "master", "commit": "16939cda184ff555938cc895cc62477c172997f9" }, - "vim-scimark": { "branch": "master", "commit": "9b66a88fa4bb87b8baab3c4aecc43b985b32e7fd" }, "vim-spellsync": { "branch": "master", "commit": "3d6dd50de9c4d953cc16638112a6ae196df41463" }, + "wezterm.nvim": { "branch": "main", "commit": "f73bba23ab4becd146fa2d0a3a16a84b987eeaca" }, "which-key.nvim": { "branch": "main", "commit": "0539da005b98b02cf730c1d9da82b8e8edb1c2d2" }, "wrapping.nvim": { "branch": "master", "commit": "3a823200c297885b70515fa8d974e1763c578e26" }, "zen-mode.nvim": { "branch": "main", "commit": "cb73b8bd0ef9d765b942db09dc762c603a89ae44" }, diff --git a/nvim/.config/nvim/lua/core/lazy.lua b/nvim/.config/nvim/lua/core/lazy.lua index 6c2c0d3..f57bf7b 100644 --- a/nvim/.config/nvim/lua/core/lazy.lua +++ b/nvim/.config/nvim/lua/core/lazy.lua @@ -36,7 +36,7 @@ require("lazy").setup({ defaults = { lazy = true, version = "*" }, performance = { rtp = { disabled_plugins = { "netrw", "netrwPlugin" } }, - cache = { enable = false }, + cache = { enable = true }, }, }) vim.keymap.set("n", "vl", ":Lazy", { desc = "Lazy" }) diff --git a/nvim/.config/nvim/lua/core/util.lua b/nvim/.config/nvim/lua/core/util.lua index d83d8f0..93278d4 100644 --- a/nvim/.config/nvim/lua/core/util.lua +++ b/nvim/.config/nvim/lua/core/util.lua @@ -17,32 +17,67 @@ function T.get_plugin(plugin) return nil end +-- Remove the key from the vim keymap and from being displayed in which-key +-- FIXME This does not consistently currently with which-key +-- Every once in a while the maps are correctly hidden but other times they stay? +function T.unmap_key(lhs, mode) + mode = mode or "n" + if T.is_available("which-key") then + vim.keymap.set(mode, lhs, "", { desc = "which_key_ignore", silent = true }) + end + pcall(vim.keymap.del, mode, lhs) +end + -- from https://github.com/ray-x/navigator.lua/issues/247#issue-1465308677 local function path_join(...) return table.concat(vim.tbl_flatten({ ... }), "/") end +function T.set_python_env(workspace) + local base = require("core.util").get_python_venv_basefolder(workspace) + base = vim.fn.expand(base) + local p = vim.env.PATH or "" + if not base then + return + end + vim.g["python3_host_prog"] = vim.fn.expand(require("core.util").get_python_venv_bin(workspace)) + vim.env.PATH = base .. "/bin:" .. p +end +function T.get_python_venv_bin(workspace) + local pyenv = T.get_python_venv_basefolder(workspace) + if not pyenv then + -- Fallback to system Python. + return vim.fn.exepath("python3") or vim.fn.exepath("python") or "python" + end + return path_join(pyenv, "bin", "python") +end +-- cache path so we can call it multiple times +local venv_path = "" -- return the current python environment path -function T.get_python_venv(workspace) +function T.get_python_venv_basefolder(workspace) + if venv_path and venv_path ~= "" then + return venv_path + end + -- Use activated virtualenv. if vim.env.VIRTUAL_ENV then - return path_join(vim.env.VIRTUAL_ENV, "bin", "python") + venv_path = vim.env.VIRTUAL_ENV + return venv_path end -- Find and use virtualenv in workspace directory. for _, pattern in ipairs({ "*", ".*" }) do local match = vim.fn.glob(path_join(workspace, pattern, "pyvenv.cfg")) if match ~= "" then - local py = path_join("bin", "python") - match = string.gsub(match, "pyvenv.cfg", py) - return match + match = string.gsub(match, "pyvenv.cfg", "") + venv_path = match + return venv_path end match = vim.fn.glob(path_join(workspace, pattern, "poetry.lock")) if match ~= "" then local venv_base_folder = vim.fn.trim(vim.fn.system("poetry env info -p")) - return path_join(venv_base_folder, "bin", "python") + venv_path = venv_base_folder + return venv_path end end - -- Fallback to system Python. - return vim.fn.exepath("python3") or vim.fn.exepath("python") or "python" end return T diff --git a/nvim/.config/nvim/lua/plugins/completion.lua b/nvim/.config/nvim/lua/plugins/completion.lua new file mode 100644 index 0000000..cb5a3fc --- /dev/null +++ b/nvim/.config/nvim/lua/plugins/completion.lua @@ -0,0 +1,199 @@ +return { + -- completion setup + { + "hrsh7th/nvim-cmp", + branch = "main", + version = false, + dependencies = { + "andersevenrud/cmp-tmux", + "cbarrete/completion-vcard", + "f3fora/cmp-spell", + "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-path", + "hrsh7th/cmp-buffer", + "hrsh7th/cmp-calc", + "hrsh7th/cmp-cmdline", + "hrsh7th/cmp-nvim-lua", + "hrsh7th/cmp-nvim-lsp-signature-help", + "dmitmel/cmp-digraphs", + "jc-doyle/cmp-pandoc-references", + "kdheepak/cmp-latex-symbols", + "lukas-reineke/cmp-rg", + "crispgm/cmp-beancount", + { "ray-x/cmp-treesitter", dependencies = { "nvim-treesitter/nvim-treesitter" } }, + { + "saadparwaiz1/cmp_luasnip", + dependencies = { + + { + "L3MON4D3/LuaSnip", + dependencies = { + "rafamadriz/friendly-snippets", + { + "benfowler/telescope-luasnip.nvim", + dependencies = { { "nvim-telescope/telescope.nvim", optional = true } }, + config = function() + require("telescope").load_extension("luasnip") + end, + }, + }, + build = "make install_jsregexp", + config = function() + require("luasnip.loaders.from_vscode").lazy_load({ exclude = { "markdown", "quarto" } }) + require("luasnip.loaders.from_snipmate").lazy_load() + end, + }, + }, + }, + }, + config = function() + local luasnip = require("luasnip") + local cmp = require("cmp") + + local has_words_before = function() + ---@diagnostic disable-next-line:deprecated + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 + and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil + end + + local kind_icons = { + Text = "", + Method = "", + Function = "󰊕", + Constructor = "", + Field = "", + Variable = "", + Class = "", + Interface = "", + Module = "", + Property = "", + Unit = "", + Value = "V", + Enum = "", + Keyword = "", + Snippet = "", + Color = "", + File = "", + Reference = "", + Folder = "", + EnumMember = "", + Constant = "", + Struct = "", + Event = "", + Operator = "", + TypeParameter = "", + } + + cmp.setup({ + window = { documentation = cmp.config.window.bordered() }, + snippet = { + expand = function(args) + require("luasnip").lsp_expand(args.body) + end, + }, + sources = { + { name = "nvim_lua" }, + { + name = "beancount", + option = { + account = vim.env["HOME"] .. "/documents/records/budget/main.beancount", -- TODO implement dynamically + }, + }, + { name = "otter" }, + { name = "nvim_lsp" }, + { name = "nvim_lsp_signature_help" }, + { name = "luasnip", keyword_length = 1 }, + { name = "pandoc_references" }, + { name = "calc" }, + { name = "path" }, + { name = "buffer", keyword_length = 3 }, + { name = "latex_symbols" }, + { name = "spell", keyword_length = 3 }, + { name = "tmux" }, -- { name = 'rg', keyword_length = 5 }, + { name = "vCard" }, + { name = "digraphs", keyword_length = 2 }, + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping({ + i = function(fallback) + if cmp.visible() and cmp.get_active_entry() then + cmp.confirm({ + behavior = cmp.ConfirmBehavior.Replace, + select = false, + }) + else + fallback() + end + end, + s = cmp.mapping.confirm({ select = true }), + c = cmp.mapping.confirm({ + behavior = cmp.ConfirmBehavior.Replace, + select = false, + }), -- disable selection in cmd mode + }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable() + -- they way you will only jump inside the snippet region + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }), + formatting = { + fields = { "kind", "abbr", "menu" }, + format = function(entry, vim_item) + -- Kind icons, removing kind text leaving only icon + -- vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind], vim_item.kind) + vim_item.kind = string.format("%s", kind_icons[vim_item.kind]) + + -- Source + vim_item.menu = ({ + buffer = "", + calc = "󰃬", + digraphs = "∬", + latex_symbols = "𝓧", + luasnip = "", + nvim_lsp = "ℒ", + nvim_lua = "󰢱", + pandoc_references = "", + spell = "󰓆", + vCard = "󰛋", + })[entry.source.name] + return vim_item + end, + }, + }) + -- `/` cmdline setup. + cmp.setup.cmdline("/", { + mapping = cmp.mapping.preset.cmdline(), + sources = { { name = "buffer" } }, + }) + -- `:` cmdline setup. + cmp.setup.cmdline(":", { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ { name = "path" } }, { + { name = "cmdline", option = { ignore_cmds = { "Man", "!" } } }, + }), + }) + end, + event = { "InsertEnter", "CmdlineEnter" }, + }, +} diff --git a/nvim/.config/nvim/lua/plugins/config/cmp.lua b/nvim/.config/nvim/lua/plugins/config/cmp.lua deleted file mode 100644 index 49840cc..0000000 --- a/nvim/.config/nvim/lua/plugins/config/cmp.lua +++ /dev/null @@ -1,144 +0,0 @@ -local luasnip = require("luasnip") -local cmp = require("cmp") - -local has_words_before = function() - local line, col = unpack(vim.api.nvim_win_get_cursor(0)) - return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil -end - -local kind_icons = { - Text = "", - Method = "", - Function = "󰊕", - Constructor = "", - Field = "", - Variable = "", - Class = "", - Interface = "", - Module = "", - Property = "", - Unit = "", - Value = "V", - Enum = "", - Keyword = "", - Snippet = "", - Color = "", - File = "", - Reference = "", - Folder = "", - EnumMember = "", - Constant = "", - Struct = "", - Event = "", - Operator = "", - TypeParameter = "", -} - -cmp.setup({ - window = { documentation = cmp.config.window.bordered() }, - snippet = { - expand = function(args) - require("luasnip").lsp_expand(args.body) - end, - }, - sources = { - { name = "nvim_lua" }, - { - name = "beancount", - option = { - account = vim.env["HOME"] .. "/documents/records/budget/main.beancount", -- TODO implement dynamically - }, - }, - { name = "otter" }, - { name = "nvim_lsp" }, - { name = "nvim_lsp_signature_help" }, - { name = "luasnip", keyword_length = 2 }, - { name = "pandoc_references" }, - { name = "calc" }, - { name = "path" }, - { name = "buffer", keyword_length = 3 }, - { name = "latex_symbols" }, - { name = "spell", keyword_length = 3 }, - { name = "tmux" }, -- { name = 'rg', keyword_length = 5 }, - { name = "vCard" }, - { name = "digraphs", keyword_length = 2 }, - }, - mapping = cmp.mapping.preset.insert({ - [""] = cmp.mapping.scroll_docs(-4), - [""] = cmp.mapping.scroll_docs(4), - [""] = cmp.mapping({ - i = function(fallback) - if cmp.visible() and cmp.get_active_entry() then - cmp.confirm({ - behavior = cmp.ConfirmBehavior.Replace, - select = false, - }) - else - fallback() - end - end, - s = cmp.mapping.confirm({ select = true }), - c = cmp.mapping.confirm({ - behavior = cmp.ConfirmBehavior.Replace, - select = false, - }), -- disable selection in cmd mode - }), - [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_next_item() - -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable() - -- they way you will only jump inside the snippet region - elseif luasnip.expand_or_jumpable() then - luasnip.expand_or_jump() - elseif has_words_before() then - cmp.complete() - else - fallback() - end - end, { "i", "s" }), - [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_prev_item() - elseif luasnip.jumpable(-1) then - luasnip.jump(-1) - else - fallback() - end - end, { "i", "s" }), - }), - formatting = { - fields = { "kind", "abbr", "menu" }, - format = function(entry, vim_item) - -- Kind icons, removing kind text leaving only icon - -- vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind], vim_item.kind) - vim_item.kind = string.format("%s", kind_icons[vim_item.kind]) - - -- Source - vim_item.menu = ({ - buffer = "", - calc = "󰃬", - digraphs = "∬", - latex_symbols = "𝓧", - luasnip = "", - nvim_lsp = "ℒ", - nvim_lua = "󰢱", - pandoc_references = "", - spell = "󰓆", - vCard = "󰛋", - })[entry.source.name] - return vim_item - end, - }, -}) --- `/` cmdline setup. -cmp.setup.cmdline("/", { - mapping = cmp.mapping.preset.cmdline(), - sources = { { name = "buffer" } }, -}) --- `:` cmdline setup. -cmp.setup.cmdline(":", { - mapping = cmp.mapping.preset.cmdline(), - sources = cmp.config.sources({ { name = "path" } }, { - { name = "cmdline", option = { ignore_cmds = { "Man", "!" } } }, - }), -}) diff --git a/nvim/.config/nvim/lua/plugins/config/lsp.lua b/nvim/.config/nvim/lua/plugins/config/lsp.lua index e84244e..3481a46 100644 --- a/nvim/.config/nvim/lua/plugins/config/lsp.lua +++ b/nvim/.config/nvim/lua/plugins/config/lsp.lua @@ -34,7 +34,7 @@ local servers = { filetypes = { "markdown", "quarto" }, }, basedpyright = {}, - ruff_lsp = {}, + ruff = {}, serve_d = {}, tailwindcss = {}, taplo = {}, @@ -43,17 +43,7 @@ local servers = { yamlls = {}, } --- TODO installed for conform/nvim-lint so should be sourced from there not here -local to_mason = - { "stylua", "shellcheck", "shfmt", "markdownlint", "bibtex-tidy", "jq", "prettier", "ruff", unpack(servers) } -require("mason-tool-installer").setup({ - -- a list of all tools you want to ensure are installed upon - -- start - ensure_installed = to_mason, - start_delay = 3000, -}) - -local function on_attach(client, bufnr) +local function on_attach(_, bufnr) local map = vim.keymap.set map("n", "[d", "lua vim.diagnostic.goto_prev()", { buffer = bufnr, desc = "Previous diagnostic" }) map("n", "]d", "lua vim.diagnostic.goto_next()", { buffer = bufnr, desc = "Next diagnostic" }) @@ -166,21 +156,35 @@ local python_path -- ensure python virtualenv is determined automatically on lsp start lspconfig.basedpyright.setup({ on_attach = function(client, bufnr) + on_attach(client, bufnr) if python_path == nil then - python_path, _ = require("core.util").get_python_venv(client.config.root_dir) + python_path, _ = vim.fn.expand(require("core.util").get_python_venv_bin(client.config.root_dir)) end + vim.g["python3_host_prog"] = python_path -- print(string.format("[PYTHON VENV]: %s", vim.inspect(python_path))) client.config.settings.python = {} or client.config.settings.python client.config.settings.python.pythonPath = python_path - on_attach(client, bufnr) end, + settings = { + -- disable imports and linting since, we use ruff for that + pyright = { + disableOrganizeImports = true, + }, + python = { + analysis = { + ignore = { "*" }, + }, + }, + }, }) -lspconfig.ruff_lsp.setup({ +lspconfig.ruff.setup({ on_attach = function(client, bufnr) on_attach(client, bufnr) + client.server_capabilities.hoverProvider = false -- we use pyright for hover info if python_path == nil then - python_path, _ = require("core.util").get_python_venv(client.config.root_dir) + python_path, _ = vim.fn.expand(require("core.util").get_python_venv_bin(client.config.root_dir)) end + vim.g["python3_host_prog"] = python_path client.config.settings.python = {} or client.config.settings.python client.config.settings.python.pythonPath = python_path end, diff --git a/nvim/.config/nvim/lua/plugins/core.lua b/nvim/.config/nvim/lua/plugins/core.lua index 5544ca8..b1dd640 100644 --- a/nvim/.config/nvim/lua/plugins/core.lua +++ b/nvim/.config/nvim/lua/plugins/core.lua @@ -119,17 +119,17 @@ return { require("mini.bracketed").setup({ { buffer = { suffix = "b", options = {} }, - comment = { suffix = "c", options = {} }, - conflict = { suffix = "", options = {} }, + comment = { suffix = "k", options = {} }, + conflict = { suffix = "" }, -- disable to use git-conflict instead diagnostic = { suffix = "d", options = {} }, - file = { suffix = "f", options = {} }, - indent = { suffix = "", options = {} }, -- disable since we use indentscope above + file = { suffix = "", options = {} }, + indent = { suffix = "" }, -- disable since we use indentscope above jump = { suffix = "j", options = {} }, location = { suffix = "l", options = {} }, oldfile = { suffix = "o", options = {} }, quickfix = { suffix = "q", options = {} }, treesitter = { suffix = "t", options = {} }, - undo = { suffix = "", options = {} }, -- disable since I don't need it + undo = { suffix = "" }, -- disable since I don't need it window = { suffix = "w", options = {} }, yank = { suffix = "y", options = {} }, }, diff --git a/nvim/.config/nvim/lua/plugins/data_analysis.lua b/nvim/.config/nvim/lua/plugins/data_analysis.lua index 0443e6a..3eb3a05 100644 --- a/nvim/.config/nvim/lua/plugins/data_analysis.lua +++ b/nvim/.config/nvim/lua/plugins/data_analysis.lua @@ -1,4 +1,15 @@ return { + { + "jmbuhr/otter.nvim", + config = function() + require("otter").setup({ + buffers = { + set_filetype = true, + write_to_disk = false, + }, + }) + end, + }, { "quarto-dev/quarto-nvim", dependencies = { @@ -7,80 +18,180 @@ return { "vim-pandoc/vim-pandoc-syntax", "hrsh7th/nvim-cmp", "nvim-treesitter/nvim-treesitter", + { "benlubas/molten-nvim", optional = true }, }, config = function() + require("core.util").set_python_env() + require("quarto").setup({ lspFeatures = { enabled = true, languages = { "r", "python", "julia", "bash" }, - diagnostics = { enabled = false, triggers = { "BufWritePost" } }, - completion = { enabled = true }, }, codeRunner = { enabled = true, - default_method = "molten", + default_method = "slime", + ft_runners = { + python = "molten", + quarto = "molten", + }, }, }) + local map = vim.keymap.set + map("n", "C", require("quarto.runner").run_cell, { desc = "run cell" }) + map("n", "ca", require("quarto.runner").run_above, { desc = "run cells above" }) + map("n", "cb", require("quarto.runner").run_below, { desc = "run cells below" }) + map("n", "cA", require("quarto.runner").run_all, { desc = "run all similar cells" }) + map("n", "]c", "/^```{}:nohl", { desc = "Codecell forward" }) + map("n", "[c", "?^```n}:nohl", { desc = "Codecell last" }) + map("n", "co", "o```{python}```k", { desc = "Insert quarto cell below" }) + map("n", "cO", "O```{python}```k", { desc = "Insert quarto cell above" }) end, ft = { "quarto" }, }, - -- REPL work + { + "vhyrro/luarocks.nvim", + priority = 1001, -- this plugin needs to run before anything else + opts = { + rocks = { "magick" }, + }, + }, + -- image display { "3rd/image.nvim", + dependencies = { "luarocks.nvim" }, + cond = vim.fn.executable("magick") == 1, -- only runs if imagemagick installed config = function() - -- Example for configuring Neovim to load user-installed installed Lua rocks: - package.path = package.path .. ";" .. vim.fn.expand("$HOME") .. "/.luarocks/share/lua/5.1/?/init.lua;" - package.path = package.path .. ";" .. vim.fn.expand("$HOME") .. "/.luarocks/share/lua/5.1/?.lua;" - require("image").setup({ - backend = "kitty", - integrations = { - markdown = { - enabled = true, - download_remote_images = true, - only_render_image_at_cursor = true, - filetypes = { "markdown", "vimwiki", "quarto" }, - }, - }, - }) + local integrations = {} + if vim.treesitter.language.get_lang("markdown") then + integrations["markdown"] = { + enabled = true, + clear_in_insert_mode = true, + download_remote_images = true, + only_render_image_at_cursor = true, + filetypes = { "markdown", "vimwiki", "quarto" }, + } + end + if vim.treesitter.language.get_lang("norg") then + integrations["neorg"] = { + enabled = true, + clear_in_insert_mode = true, + download_remote_images = true, + only_render_image_at_cursor = true, + filetypes = { "norg" }, + } + end + if next(integrations) ~= nil then -- only set up if we have at least 1 TS parser + require("image").setup({ + backend = "kitty", + integrations = integrations, + }) + vim.g.molten_image_provider = "image.nvim" + end end, - ft = { "markdown", "vimwiki", "quarto" }, + ft = { "markdown", "vimwiki", "quarto", "norg", "python" }, + priority = 51, }, + -- REPL work { "benlubas/molten-nvim", + dependencies = { + { "willothy/wezterm.nvim", config = true }, + { "3rd/image.nvim", optional = true }, + }, build = ":UpdateRemotePlugins", config = function() - vim.g.molten_image_provider = "none" -- image integration does NOT work currently :-( + vim.g.molten_image_provider = vim.g.molten_image_provider or "wezterm" vim.g.molten_auto_open_output = false + vim.g.molten_virt_text_output = true + if vim.fn.has("nvim-0.10") then + vim.g.molten_output_show_more = true + end + vim.api.nvim_create_autocmd("User", { + pattern = "MoltenInitPost", + callback = function() + local map = vim.keymap.set + if require("core.util").is_available("which-key") then + require("which-key").register({ ["c"] = { name = "+codecells" } }) + end + -- Operate jupyter notebooks from within vim + map( + "n", + "cc", + ":MoltenEvaluateOperator", + { desc = "evaluate operator", silent = true } + ) + map("n", "cl", ":MoltenEvaluateLine", { desc = "evaluate line", silent = true }) + map( + "x", + "c", + ":MoltenEvaluateVisual", + { desc = "evaluate visual", silent = true } + ) + map( + "n", + "cr", + ":MoltenReevaluateCell", + { desc = "reevaluate cell", silent = true } + ) + map( + "n", + "cp", + ":noautocmd :MoltenEnterOutput", + { silent = true, desc = "show output" } + ) + map("n", "cP", function() + vim.cmd("MoltenHideOutput") + vim.cmd("MoltenDelete") + end, { silent = true, desc = "hide output" }) + map("n", "ci", ":MoltenImagePopup", { silent = true, desc = "open image" }) + map("n", "cI", ":MoltenInterrupt", { desc = "interrupt cell", silent = true }) + map("n", "cD", ":MoltenDeinit", { desc = "de-init molten", silent = true }) + map("n", "cR", ":MoltenRestart", { desc = "restart molten", silent = true }) + -- FIXME: Works for toggling TO virt text but not back + local function toggle_virtual_text_output() + if vim.g.molten_virt_text_output then + vim.fn.MoltenUpdateOption("molten_virt_text_output", false) + return + end + vim.fn.MoltenUpdateOption("molten_virt_text_output", true) + end + map( + "n", + "cV", + toggle_virtual_text_output, + { desc = "toggle virtual output", silent = true } + ) + end, + }) + vim.api.nvim_create_autocmd("User", { + pattern = "MoltenDeinitPost", + callback = function() + local unmap = require("core.util").unmap_key + unmap("cc") + unmap("cl") + unmap("c", "x") + unmap("cr") + unmap("cR") + unmap("cp") + unmap("cP") + unmap("co") + unmap("cD") + unmap("ci") + unmap("cV") + local map = vim.keymap.set + map("n", "cI", ":MoltenInit", { desc = "init molten", silent = true }) + end, + }) end, - cmd = { - "MoltenInfo", - "MoltenInit", - "MoltenDeinit", - "MoltenGoto", - "MoltenNext", - "MoltenPrev", - "MoltenEvaluateLine", - "MoltenEvaluateVisual", - "MoltenEvaluateOperator", - "MoltenEvaluateArgument", - "MoltenReevaluateCell", - "MoltenDelete", - "MoltenShowOutput", - "MoltenHideOutput", - "MoltenEnterOutput", - "MoltenInterrupt", - "MoltenRestart", - "MoltenSave", - "MoltenLoad", - "MoltenExportOutput", - }, - ft = { "quarto", "python" }, - lazy = false, + ft = { "norg", "quarto", "python" }, keys = { { "vn", ":MoltenInfo" }, + { "ci", ":MoltenInit" }, }, }, + -- Edit code blocks in md/quarto using whatever language is { "AckslD/nvim-FeMaco.lua", @@ -92,8 +203,10 @@ return { dependencies = { "nvim-treesitter/nvim-treesitter", }, + keys = { + { "ce", ":FeMaco", desc = "edit codecell" }, + }, }, - -- MARKDOWN ONLY -- Evaluate markdown code blocks { @@ -108,4 +221,27 @@ return { }, lazy = false, }, + + -- Open ipynb Jupyter notebooks as if they're quarto files + -- requires jupytext to be installed + { + "GCBallesteros/jupytext.nvim", + opts = { + style = "light", + custom_language_formatting = { + python = { + extension = "qmd", + style = "quarto", + force_ft = "quarto", + }, + r = { + extension = "qmd", + style = "quarto", + force_ft = "quarto", + }, + }, + }, + cond = vim.fn.executable("jupytext") == 1, -- only runs if imagemagick installed + lazy = false -- does not work in lazy mode + }, } diff --git a/nvim/.config/nvim/lua/plugins/ide.lua b/nvim/.config/nvim/lua/plugins/ide.lua index f2b88a7..3adafec 100644 --- a/nvim/.config/nvim/lua/plugins/ide.lua +++ b/nvim/.config/nvim/lua/plugins/ide.lua @@ -3,11 +3,11 @@ local linters = { bash = { "shellcheck" }, javascript = { "eslint_d" }, javascriptreact = { "eslint_d" }, - markdown = { "markdownlint", "vale" }, - quarto = { "markdownlint", "vale" }, + markdown = { "markdownlint" }, + quarto = { "markdownlint" }, sh = { "shellcheck" }, svelte = { "eslint_d" }, - text = { "vale" }, + text = {}, typescript = { "eslint_d" }, typescriptreact = { "eslint_d" }, } @@ -96,16 +96,14 @@ return { "williamboman/mason-lspconfig.nvim", cmd = { "LspInstall", "LspUninstall" }, }, - { "WhoIsSethDaniel/mason-tool-installer.nvim" }, }, event = { "BufReadPost", "BufNewFile", "BufWritePre" }, - after = { "nvim-cmp" }, config = function() require("plugins.config.lsp") end, keys = { { "vs", ":LspInfo", desc = "LspInfo" } }, }, - -- very very pretty lsp 'peek' menus + -- pretty lsp 'peek' menus { "DNLHC/glance.nvim", opts = { border = { enable = true }, theme = { enable = true, mode = "auto" } }, @@ -114,118 +112,98 @@ return { -- linting setup { - "mfussenegger/nvim-lint", - config = function() - require("lint").linters_by_ft = linters - vim.api.nvim_create_autocmd({ "BufWritePost", "InsertLeave" }, { - callback = function() - if not vim.g.disable_autolint then - require("lint").try_lint() - end + "rshkarin/mason-nvim-lint", + dependencies = { + { + "mfussenegger/nvim-lint", + config = function() + require("lint").linters_by_ft = linters + vim.api.nvim_create_autocmd({ "BufWritePost", "InsertLeave" }, { + callback = function() + if not vim.g.disable_autolint then + require("lint").try_lint() + end + end, + }) end, - }) - end, + dependencies = { "williamboman/mason.nvim" }, + }, + }, event = { "BufReadPost", "BufNewFile", "BufWritePre" }, + opts = {}, }, -- formatting setup { - "stevearc/conform.nvim", - config = function() - require("conform").setup({ - lsp_fallback = true, - format_after_save = function(bufnr) - if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then - return - end - return { lsp_fallback = true } + "zapling/mason-conform.nvim", + dependencies = { + { + "stevearc/conform.nvim", + config = function() + require("conform").setup({ + lsp_fallback = true, + format_after_save = function(bufnr) + if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + return + end + return { lsp_fallback = true } + end, + formatters_by_ft = formatters, + formatters = { + -- enable python isort functionality + ruff_fix = { + prepend_args = { "--select", "I" }, + }, + }, + }) + vim.api.nvim_create_user_command("FormatDisable", function(args) + if args.bang then + -- FormatDisable! will disable formatting just for this buffer + vim.b.disable_autoformat = true + else + vim.g.disable_autoformat = true + end + end, { + desc = "Disable formatting on save", + bang = true, + }) + vim.api.nvim_create_user_command("FormatEnable", function() + vim.b.disable_autoformat = false + vim.g.disable_autoformat = false + end, { + desc = "Enable formatting on save", + }) end, - formatters_by_ft = formatters, - formatters = { - -- enable python isort functionality - ruff_fix = { - prepend_args = { "--select", "I" }, + cmd = { "ConformInfo" }, + keys = { + { + "ll", + function() + require("conform").format({ async = true, lsp_fallback = true }) + end, + desc = "Format buffer", + }, + { + "lL", + function() + vim.g.disable_autoformat = not vim.g.disable_autoformat + end, + desc = "Toggle AutoFormat", + }, + { + "vf", + ":ConformInfo", + desc = "ConformInfo", }, }, - }) - vim.api.nvim_create_user_command("FormatDisable", function(args) - if args.bang then - -- FormatDisable! will disable formatting just for this buffer - vim.b.disable_autoformat = true - else - vim.g.disable_autoformat = true - end - end, { - desc = "Disable formatting on save", - bang = true, - }) - vim.api.nvim_create_user_command("FormatEnable", function() - vim.b.disable_autoformat = false - vim.g.disable_autoformat = false - end, { - desc = "Enable formatting on save", - }) - end, - cmd = { "ConformInfo" }, + init = function() + -- If you want the formatexpr, here is the place to set it + vim.o.formatexpr = "v:lua.require'conform'.formatexpr()" + end, + }, + }, event = { "BufReadPost", "BufNewFile", "BufWritePre" }, - keys = { - { - "ll", - function() - require("conform").format({ async = true, lsp_fallback = true }) - end, - desc = "Format buffer", - }, - { - "lL", - function() - vim.g.disable_autoformat = not vim.g.disable_autoformat - end, - desc = "Toggle AutoFormat", - }, - { - "vf", - ":ConformInfo", - desc = "ConformInfo", - }, - }, - init = function() - -- If you want the formatexpr, here is the place to set it - vim.o.formatexpr = "v:lua.require'conform'.formatexpr()" - end, - }, - - -- completion setup - { - "hrsh7th/nvim-cmp", - branch = "main", - dependencies = { - "andersevenrud/cmp-tmux", - "cbarrete/completion-vcard", - "f3fora/cmp-spell", - "hrsh7th/cmp-nvim-lsp", - "hrsh7th/cmp-path", - "hrsh7th/cmp-buffer", - "hrsh7th/cmp-calc", - "hrsh7th/cmp-cmdline", - "hrsh7th/cmp-nvim-lua", - "hrsh7th/cmp-nvim-lsp-signature-help", - "dmitmel/cmp-digraphs", - "jc-doyle/cmp-pandoc-references", - "kdheepak/cmp-latex-symbols", - "lukas-reineke/cmp-rg", - "crispgm/cmp-beancount", - "ray-x/cmp-treesitter", - "saadparwaiz1/cmp_luasnip", - { - "L3MON4D3/LuaSnip", - dependencies = { "rafamadriz/friendly-snippets" }, - }, - }, - config = function() - require("plugins.config.cmp") - end, - event = { "InsertEnter", "CmdlineEnter" }, + opts = {}, }, -- useful quickfix-like buffer diff --git a/nvim/.config/nvim/lua/plugins/prose.lua b/nvim/.config/nvim/lua/plugins/prose.lua index d6c6327..7dfbbaa 100644 --- a/nvim/.config/nvim/lua/plugins/prose.lua +++ b/nvim/.config/nvim/lua/plugins/prose.lua @@ -1,4 +1,4 @@ -local writing_ft = { "quarto", "pandoc", "markdown", "text", "tex" } +local writing_ft = { "quarto", "pandoc", "markdown", "text", "tex", "typst" } local prose_plugs = { -- UI improvements @@ -69,6 +69,26 @@ local prose_plugs = { ft = writing_ft, }, + -- easy copy paste of images into markup files + { + "HakonHarnes/img-clip.nvim", + event = "VeryLazy", + opts = { + filetypes = { + quarto = { + url_encode_path = true, + template = "![$CURSOR]($FILE_PATH)", + download_images = false, + }, + }, + }, + cmd = { "PasteImage" }, + keys = { + { "pp", "PasteImage", desc = "Paste image from system clipboard" }, + }, + ft = writing_ft, + }, + -- bring zettelkasten commands { "mickael-menu/zk-nvim", @@ -111,6 +131,7 @@ local prose_plugs = { "ZkOrphans", }, keys = { + -- additional key instpirations https://github.com/al1-ce/MonolithVim/blob/master/after/ftplugin/markdown.lua { "ni", "edit ~/documents/notes/index.md", desc = "open index", silent = true }, { "nn", "ZkNotes { sort = { 'modified' } }", desc = "note list" }, { diff --git a/nvim/.config/nvim/lua/plugins/treesitter.lua b/nvim/.config/nvim/lua/plugins/treesitter.lua index 5db7903..8ed1ff5 100644 --- a/nvim/.config/nvim/lua/plugins/treesitter.lua +++ b/nvim/.config/nvim/lua/plugins/treesitter.lua @@ -2,6 +2,22 @@ return { { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate", + -- show current cursor context at top of buffer + -- improves commenting plugin above by using ts + dependencies = { + { "romgrk/nvim-treesitter-context", config = true }, + "JoosepAlviste/nvim-ts-context-commentstring", + "RRethy/nvim-treesitter-textsubjects", + "windwp/nvim-ts-autotag", + "RRethy/nvim-treesitter-endwise", + -- rainbow brackets using treesitter + { + "HiPhish/rainbow-delimiters.nvim", + config = function() + require("rainbow-delimiters.setup").setup({}) + end, + }, + }, config = function() require("nvim-treesitter.configs").setup({ -- one of "all", "maintained" (parsers with maintainers), or a list of languages @@ -63,7 +79,7 @@ return { filetype = "nu", } end, - event = { "BufReadPost", "BufNewFile", "BufWritePre", "VeryLazy" }, + event = { "VeryLazy" }, cmd = { "TSBufDisable", "TSBufEnable", @@ -79,24 +95,9 @@ return { "TSUpdate", "TSUpdateSync", }, - - -- show current cursor context at top of buffer - -- improves commenting plugin above by using ts - dependencies = { - { "romgrk/nvim-treesitter-context", config = true }, - "JoosepAlviste/nvim-ts-context-commentstring", - "RRethy/nvim-treesitter-textsubjects", - "windwp/nvim-ts-autotag", - "RRethy/nvim-treesitter-endwise", + keys = { + { "si", "Inspect", desc = "treesitter element", silent = true }, + { "sI", "InspectTree", desc = "treesitter tree", silent = true }, }, }, - -- rainbow brackets using treesitter - { - "https://gitlab.com/HiPhish/rainbow-delimiters.nvim", - lazy = false, - event = { "BufReadPost", "BufNewFile", "BufWritePre", "VeryLazy" }, - config = function() - require("rainbow-delimiters.setup").setup({}) - end, - }, } diff --git a/nvim/.config/nvim/lua/plugins/ui.lua b/nvim/.config/nvim/lua/plugins/ui.lua index fbf0ed9..9e829c3 100644 --- a/nvim/.config/nvim/lua/plugins/ui.lua +++ b/nvim/.config/nvim/lua/plugins/ui.lua @@ -2,18 +2,46 @@ return { -- statusline { "nvim-lualine/lualine.nvim", - requires = { "nvim-tree/nvim-web-devicons", config = true }, + dependencies = { { "nvim-tree/nvim-web-devicons", config = true } }, config = function() - -- FIXME: Errors out on no pynvim installed - -- local function molten() - -- if - -- require("core.util").is_available("molten.status") - -- and require("molten.status").initialized() ~= "" - -- then - -- return "󱪄" - -- end - -- return "" - -- end + local has_pynvim = -1 + -- if molten exists, is initialized and connected to a kernel + -- show it in the statusline + local function molten() + local function checked_pynvim(_, exitcode) + if exitcode == 0 then + has_pynvim = 1 + else + has_pynvim = 0 + end + end + if has_pynvim == 0 then + return "" + elseif has_pynvim == -1 then + vim.fn.jobstart({ "python", "-c", "from neovim import VERSION" }, { on_exit = checked_pynvim }) + end + if + has_pynvim == 1 + and require("core.util").is_available("molten.status") + and require("molten.status").kernels() ~= "" + then + return "󱪄" + end + return "" + end + + -- count number of selected lines and characters + -- stolen: https://github.com/chrisgrieser/.config/blob/8af1841ba24f7c81c513e12f853b52f530ef5b37/nvim/lua/plugins/lualine.lua#L80C1-L87C4 + local function selectionCount() + local isVisualMode = vim.fn.mode():find("[Vv]") + if not isVisualMode then + return "" + end + local starts = vim.fn.line("v") + local ends = vim.fn.line(".") + local lines = starts <= ends and ends - starts + 1 or starts - ends + 1 + return " " .. tostring(lines) .. "L " .. tostring(vim.fn.wordcount().visual_chars) .. "C" + end require("lualine").setup({ options = { icons_enabled = true, @@ -27,9 +55,9 @@ return { lualine_a = { "mode" }, lualine_b = { "branch", "diff", "diagnostics" }, lualine_c = { "filename" }, - lualine_x = { "encoding", "fileformat", "filetype", "molten" }, + lualine_x = { "encoding", "fileformat", "filetype", molten }, lualine_y = { "progress" }, - lualine_z = { "location" }, + lualine_z = { selectionCount, "location" }, }, inactive_sections = { lualine_a = {}, @@ -40,7 +68,18 @@ return { lualine_z = {}, }, tabline = {}, - extensions = { "quickfix", "toggleterm" }, + extensions = { + "aerial", + "lazy", + "man", + "mason", + "nvim-dap-ui", + "nvim-tree", + "oil", + "quickfix", + "toggleterm", + "trouble", + }, }) end, event = { "VeryLazy" }, @@ -58,10 +97,10 @@ return { }, }, event = { "VeryLazy" }, - cmd = {"Fidget"}, + cmd = { "Fidget" }, keys = { { "sh", "Fidget history", { silent = true, desc = "show notification history" } }, - } + }, }, -- make all vim.ui interfaces prettyy { "stevearc/dressing.nvim", config = true, event = "VeryLazy" }, diff --git a/nvim/.config/nvim/snippets/markdown.snippets b/nvim/.config/nvim/snippets/markdown.snippets new file mode 100644 index 0000000..d4b5709 --- /dev/null +++ b/nvim/.config/nvim/snippets/markdown.snippets @@ -0,0 +1,80 @@ +# Markdown snippets +# Combination of snips from friendly-snippets and vim-snippets repos + +snippet h1 Heading level 1 + # ${0} + +snippet h2 Heading level 2 + ## ${0} + +snippet h3 Heading level 3 + ### ${0} + +snippet h4 Heading level 4 + #### ${0} + +snippet h5 Heading level 5 + ##### ${0} + +snippet h6 Heading level 6 + ##### ${0} + +snippet ] Link + [${1:text}](${2:link}) + +snippet ]h Weblink + [${1:text}](https://${2:address}) + +snippet ]c Link filled with clipboard contents + [${1:text}](${2:`@+`}) + +snippet ]: Link reference style + [${1:id}]: ${2:text} + +snippet ]] Footnote + [^${1:id}]${0} + + [^${1:id}]: ${2:text} + +snippet img Image link + ![${1:alt}](${2:link}) + +snippet imgc Image link with clipboard content + ![${1:alt}](${2:`@+`}) + +snippet ** Bold + **$0** +snippet __ Bold + __$0__ +snippet --- Frontmatter + --- + $0 + --- + +# codeblocks +snippet `` Codeblock with language + \`\`\`${1:language} + ${2:code} + \`\`\` + +# table +snippet tb Simple table + | ${5:factors} | ${1:a} | ${2:b} | + | ------------- |------------- | ------- | + | ${3:f1} | ${0} | N | + | ${4:f2} | N | N | + +# tasklists +snippet tl Tasklist item + - [ ] ${0:item} + +snippet tl3 Tasklist item + - [ ] ${1:item} + - [ ] ${2:item} + - [ ] ${0:item} + +# super/subscript - pandoc/extended markdown only +snippet sub Subscript + ~${0}~ +snippet sup Superscript + ^${0}^ diff --git a/nvim/.config/nvim/snippets/quarto.snippets b/nvim/.config/nvim/snippets/quarto.snippets new file mode 100644 index 0000000..47e9533 --- /dev/null +++ b/nvim/.config/nvim/snippets/quarto.snippets @@ -0,0 +1,100 @@ +# Quarto extensions to markdown + +extends markdown + +# definitions list +snippet : Definition list + $1 + : $0 + +snippet `` Codecell with language + \`\`\`{${1:language}} + ${2:code} + \`\`\` + +snippet ``p Codecell with language + \`\`\`{python} + ${2:code} + \`\`\` + +snippet ``r Codecell with language + \`\`\`{r} + ${2:code} + \`\`\` + +snippet pyfig2 Sub-Figures from python codecell + \`\`\`{python} + #| label: fig-${1:label} + #| fig-cap: "${2:caption}" + #| fig-subcap: + #| - "${3:subcap1}" + #| - "${3:subcap2}" + #| layout-ncol: 2 + + ${0:code} + \`\`\` + +snippet pyfig Figure from python codecell + \`\`\`{python} + #| label: fig-${1:label} + #| fig-cap: "${2:caption}" + + ${0:code} + \`\`\` + +snippet fig General figure + ![${1:caption}](${3:figure}){#fig-${2:label}} + +snippet pytab Figure from python codecell + \`\`\`{python} + #| label: tbl-${1:label} + #| tbl-cap: "${2:caption}" + + ${0:code} + \`\`\` + +snippet fref Figure crossref + @fig-${1:label} +snippet tref Table crossref + @tbl-${1:label} +snippet sref Section crossref + @sec-${1:label} +snippet eref Equation crossref + @eq-${1:label} + +snippet cite Citation + [@${1:bib-key}] + +snippet fn Footnote + [^${1:id}] + + [^${1}]: ${2:text} + +snippet shortcode Shortcode + {{< $0 >}} + +snippet div Div block + ::: {.${1:class}} + $0 + ::: + +snippet note Callout note + ::: {.callout-note} + $0 + ::: +snippet warn Callout warning + ::: {.callout-warning} + $0 + ::: +snippet import Callout important + ::: {.callout-important} + $0 + ::: +snippet tip Callout tip + ::: {.callout-tip} + $0 + ::: +snippet caut Callout caution + ::: {.callout-caution} + $0 + ::: diff --git a/terminal/.config/wezterm/maps.lua b/terminal/.config/wezterm/maps.lua index 40e1b43..b519d12 100644 --- a/terminal/.config/wezterm/maps.lua +++ b/terminal/.config/wezterm/maps.lua @@ -52,7 +52,7 @@ local keys = { mods = "LEADER", action = act.ShowLauncherArgs({ flags = "FUZZY|WORKSPACES" }), }, - { key = "t", mods = "LEADER", action = act.ShowTabNavigator }, + { key = "T", mods = "LEADER", action = act.ShowTabNavigator }, { key = "[", mods = "LEADER", action = act.ActivateCopyMode }, { key = "r", @@ -100,7 +100,9 @@ local keys = { action = act.EmitEvent("ActivatePaneDirection-Right"), }, { key = "a", mods = "CTRL|ALT", action = act.EmitEvent("toggle-leader") }, - { key = "T", mods = "CTRL", action = act.EmitEvent("toggle-tabbar") }, + { key = "t", mods = "LEADER", action = act.EmitEvent("toggle-tabbar") }, + { key = "Enter", mods = "CTRL", action = wezterm.action({ SendString = "\x1b[13;5u" }) }, + { key = "Enter", mods = "SHIFT", action = wezterm.action({ SendString = "\x1b[13;2u" }) }, } -- Leader + number to activate that tab for i = 1, 8 do