diff --git a/README.md b/README.md new file mode 100644 index 0000000..7a9b1ca --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Neovim configuration in pure lua + +You can configure the current semester that you are in for university integrations. +There are certain things required like `make` and `npm` for various plugins. + diff --git a/init.lua b/init.lua index 1764e03..575b05e 100644 --- a/init.lua +++ b/init.lua @@ -1,12 +1,3 @@ -- Nvim config by Jonas Hahn --- set a diff flag --- this stands for diff mode -if vim.o.diff then - vim.g.diffm = true -else - vim.g.diffm = false -end - require("config.init") - diff --git a/lazy-lock.json b/lazy-lock.json index 97e4759..8778c51 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -14,15 +14,16 @@ "lazygit.nvim": { "branch": "main", "commit": "3c524ebec6072568064235c407195e9f9fd0cb8a" }, "lspsaga.nvim": { "branch": "main", "commit": "8efe00d6aed9db6449969f889170f1a7e43101a1" }, "lualine.nvim": { "branch": "master", "commit": "b8c23159c0161f4b89196f74ee3a6d02cdc3a955" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "1ec4da522fa49dcecee8d190efda273464dd2192" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "5e085efe67fccb13372d54331d849219662a7e93" }, "mason.nvim": { "branch": "main", "commit": "7dc4facca9702f95353d5a1f87daf23d78e31c2a" }, "nvim-cmp": { "branch": "main", "commit": "b5311ab3ed9c846b585c0c15b7559be131ec4be9" }, - "nvim-lspconfig": { "branch": "master", "commit": "52364267cd7edbc0e9b25ab3bfb1c8f45dd58fde" }, + "nvim-lspconfig": { "branch": "master", "commit": "408cf07b97535825cca6f1afa908d98348712ba6" }, "nvim-tree.lua": { "branch": "master", "commit": "fefa335f1c8f690eb668a1efd18ee4fc6d64cd3e" }, "nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" }, + "nvim-web-devicons": { "branch": "master", "commit": "f66cdfef5e84112045b9ebc3119fee9bddb3c687" }, "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, "telekasten.nvim": { "branch": "main", "commit": "b3ac2b07f2df504bb80112fec349714086a80037" }, - "telescope.nvim": { "branch": "master", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }, + "telescope.nvim": { "branch": "master", "commit": "b4da76be54691e854d3e0e02c36b0245f945c2c7" }, "toggleterm.nvim": { "branch": "main", "commit": "9a88eae817ef395952e08650b3283726786fb5fb" }, "which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" } } diff --git a/lazyvim.json b/lazyvim.json deleted file mode 100644 index a28f5eb..0000000 --- a/lazyvim.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extras": [ - - ], - "news": { - "NEWS.md": "10960" - }, - "version": 8 -} \ No newline at end of file diff --git a/lua/config/autocmds.lua b/lua/config/autocmds.lua index 98338ef..1577c75 100644 --- a/lua/config/autocmds.lua +++ b/lua/config/autocmds.lua @@ -1,70 +1,8 @@ - --- Autocommands - -vim.cmd(':colorscheme gruvbox') - -if vim.g.diffm then --- vim.api.nvim_create_autocmd("VimEnter", { --- callback = function() --- -- Create a new empty buffer --- vim.cmd("enew") --- --- -- Your multiline message --- local lines = { --- "Welcome to Neovim!", --- "", --- "You are in Diff Mode!", --- "Press do to open the Difftab.", --- "", --- "Good luck!" --- } --- --- -- Get dimensions --- local width = vim.api.nvim_get_option("columns") --- local height = vim.api.nvim_get_option("lines") --- --- -- Center vertically --- local start_line = math.floor((height - #lines) / 3) --- --- -- Insert empty lines at the top --- for _ = 1, start_line do --- vim.api.nvim_buf_set_lines(0, -1, -1, false, {""}) --- end --- --- -- Center horizontally and insert text --- for _, line in ipairs(lines) do --- local padding = math.floor((width - #line) / 2) --- local padded_line = string.rep(" ", math.max(padding, 0)) .. line --- vim.api.nvim_buf_set_lines(0, -1, -1, false, {padded_line}) --- end --- --- -- Make buffer not modifiable --- vim.bo.modifiable = false --- vim.bo.buflisted = false --- end --- }) - -end - - -vim.api.nvim_create_user_command("Ex", function() - if vim.opt.diff:get() then - -- require("diffview").open() - print("running with diff view mode -> No ex") - else - -- fallback if not in diff mode (optional) - -- vim.cmd("Explore") -- or do nothing - -- Just disable EX - print("You have tree view (no ex anymore)") - end -end, {}) - - -- Save the last file on exit vim.api.nvim_create_autocmd("VimLeave", { callback = function() -- Save the last file path to a file - local last_file = vim.fn.expand('%:p') -- Get the absolute path of the current file + local last_file = vim.fn.expand('%:p') -- Get the absolute path of the current file if last_file ~= "" then local file = io.open(vim.fn.stdpath('data') .. "/lastfile.txt", "w") if file then @@ -74,13 +12,3 @@ vim.api.nvim_create_autocmd("VimLeave", { end end, }) - --- Setting a transparent background -function Transparent(color) - color = color or "gruvbox" - vim.cmd.colorscheme(color) - vim.api.nvim_set_hl(0, "Normal", { bg = "none" }) - vim.api.nvim_set_hl(0, "NormalFloat", { bg = "none" }) -end -Transparent() - diff --git a/lua/config/colorscheme.lua b/lua/config/colorscheme.lua deleted file mode 100644 index e69de29..0000000 diff --git a/lua/config/init.lua b/lua/config/init.lua index e0dfb1a..711d748 100644 --- a/lua/config/init.lua +++ b/lua/config/init.lua @@ -1,8 +1,7 @@ -- Load lazy first require('config.lazy') --- General settings +-- General settings for nvim require('config.options') require('config.keymaps') require('config.autocmds') -require('config.lsp') diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index 66c7409..2389894 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -1,292 +1,247 @@ --- ########################### --- the heart of neovim ####### --- ########################### +-- Custom keymaps -require("helpers.functions") +require("utils.functions") +require("custom.uni") --- gloabal settings +local season = "S2" + +local links = require("utils.linker") +local user = vim.fn.system('whoami'):gsub('\n', '') +local api = require("nvim-tree.api") +local builtin = require('telescope.builtin') + +local function open_cal() + local current_date = os.date("%Y-%m-%d") + local week_number = os.date("%V") + local day_of_week = os.date("%a") + local path = "~/synced/brainstore/calendar/calendar_" .. os.date("%Y") .. ".txt" + local keys = ":e " .. + path .. "/" .. current_date .. " w" .. tonumber(week_number) .. " " .. day_of_week .. "$" + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), 'n', true) +end + +------------------------------------------------------- +--------------------- KEYMAPS ------------------------- +------------------------------------------------------- + +-- Fast quitter vim.keymap.set('n', 'q', function() - local success, _ = pcall(function() - vim.cmd('wa') -- Write (save) all buffers + pcall(function() + vim.cmd('wa') end) - vim.cmd('qa!') -- Quit all buffers forcefully + vim.cmd('qa!') end) +-- Fast window switch vim.keymap.set("n", "w", "w") +--------------------- NORMAL ------------------------- + +vim.keymap.set("n", "L", ":BufferNext", { silent = true }) +vim.keymap.set("n", "n", "nzz", { silent = true }) +vim.keymap.set("n", "N", "Nzz", { silent = true }) +vim.keymap.set("n", "H", ":BufferPrevious", { silent = true }) +vim.keymap.set("n", "", "zz", { silent = true }) +vim.keymap.set("n", "", "zz", { silent = true }) +vim.keymap.set("n", "", "zz", { silent = true }) +vim.keymap.set("n", "", "zz", { silent = true }) + +vim.keymap.set('n', 'a', 'm9ggVG"+y`9') +vim.keymap.set('n', 'va', 'ggVG') + +-- Launch panel if nothing is typed after z +vim.keymap.set("n", "z", "Telekasten panel") + +-- Most used functions +vim.keymap.set("n", "zf", "Telekasten find_notes") +vim.keymap.set("n", "zg", "Telekasten search_notes") +vim.keymap.set('n', 'zq', ':e ~/synced/brainstore/zettelkasten/input.txt`.zz') +vim.keymap.set("n", "zd", "Telekasten goto_today") +vim.keymap.set("n", "zr", "Telekasten rename_note") +vim.keymap.set("n", "zz", "Telekasten follow_link") +vim.keymap.set("n", "zn", "Telekasten new_note") +vim.keymap.set("n", "zb", "Telekasten show_backlinks") +vim.keymap.set("n", "zw", "Telekasten find_weekly_notes") +vim.keymap.set("n", "zI", "Telekasten insert_img_link") + +vim.keymap.set("n", "me", ":mes") +vim.keymap.set("n", "", ":ToggleTerm") +vim.keymap.set("t", "", ":ToggleTerm") + +vim.keymap.set("n", "snt", "set nu") +vim.keymap.set("n", "snf", "set nonu") + +-- Call insert link automatically when we start typing a link +vim.keymap.set("n", "il", "Telekasten insert_link") + +vim.keymap.set("n", "nv", function() + select_course_directory() +end, { desc = "Open UniCourse menu" }) + + +vim.keymap.set('n', 'ca', 'ggVGd') +vim.keymap.set("n", "bd", ":BufferDelete", { silent = true }) + +-- Typstar stuff +vim.keymap.set("n", "ti", ":TypstarInsertRnote", { silent = true }) +vim.keymap.set("n", "to", ":TypstarOpenDrawing", { silent = true }) + +-- Get a ready to use terminal +vim.keymap.set('n', 'tr', ':tabnew:termi') +vim.keymap.set("n", "tt", ":Telescope", { desc = "Follow Link" }) + +-- This needs to be refined for quick access to a new file or a recently edited one +vim.keymap.set('n', 'ov', open_vorlesung) +-- new quick note file +-- TODO: make this smarter +vim.keymap.set("n", "nn", ":e ~/synced/brainstore/zettelkasten/quick", { silent = true }) + +vim.keymap.set("n", "r", set_root) + +-- Quickly open some buffers +vim.keymap.set('n', 'occ', ':e ~/.config/nvim/init.lua`.zz') +vim.keymap.set('n', 'oct', ':e ~/synced/vault/contacts/contacts.txt`.zz') +vim.keymap.set('n', 'ock', ':e ~/.config/nvim/lua/config/keymaps.lua`.zz') +vim.keymap.set('n', 'ocd', ':e ~/.config/nvim/lua/config/autocmds.lua`.zz') +vim.keymap.set('n', 'oco', ':e ~/.config/nvim/lua/config/options.lua`.zz') +vim.keymap.set('n', 'ocl', ':e ~/.config/nvim/lua/config/lazy.lua`.zz') +vim.keymap.set('n', 'oczl', ':e ~/.config/nvim/lua/config/lsp.lua`.zz') +vim.keymap.set('n', 'ocp', ':e ~/.config/nvim/lua/plugins/main.lua`.zz') +vim.keymap.set('n', 'ocf', ':e ~/.config/nvim/lua/utils/functions.lua`.zz') +vim.keymap.set('n', 'oca', ':e ~/.config/nvim/lua/utils/after.lua`.zz') +vim.keymap.set('n', 'oq', ':e ~/synced/brainstore/input.txt`.zz') +vim.keymap.set('n', 'ohh', ':e ~/configuration/nixos/users/' .. user .. '/home.nix`.zz') +vim.keymap.set('n', 'op', ':e ~/configuration/nixos/users/' .. user .. '/packages.nix`.zz') +vim.keymap.set('n', 'on', ':e ~/configuration/nixos/configuration.nix`.zz') +vim.keymap.set('n', 'om', ':e ~/configuration/nixos/modules') +vim.keymap.set('n', 'ow', ':e ~/synced/brainstore/waste.txt') +vim.keymap.set('n', 'oho', ':e ~/configuration/nixos/hosts') +vim.keymap.set('n', 'os', ':e ~/configuration/nixos/modules/server') +vim.keymap.set('n', 'ot', ':e ~/synced/brainstore/todos/todo.txt`.zz') +vim.keymap.set('n', 'od', ':e ~/synced/brainstore/todos/done.txt`.zz') +vim.keymap.set('n', 'ou', ':e ~/projects/university/' .. season .. '/input.txt`.zz') +vim.keymap.set('n', 'oz', ':e ~/.zshrc`.zz') +vim.keymap.set('n', 'oaa', ':e ~/.common_shell`.zz') +vim.keymap.set("n", "or", "lua open_last_file()", { noremap = true, silent = true }) + + +vim.keymap.set('n', 'ok', open_cal) +------------------------------------------------------------------------------------- + +vim.keymap.set("n", "lf", links.insert_brainstore_link, { desc = "Link Brainstore file" }) +vim.keymap.set("n", "lm", links.insert_mail_link, { desc = "Link Mail" }) +vim.keymap.set('n', 'll', ':Lazy') +vim.keymap.set("n", "lp", links.insert_project_link, { desc = "Link Project" }) +vim.keymap.set("n", "lc", links.insert_contact_link, { desc = "Link Contact" }) +vim.keymap.set("n", "ld", links.insert_date_link, { desc = "Link Contact" }) + +-- Nvim tree +vim.keymap.set("n", "e", function() + api.tree.toggle({ find_file = true, update_root = true, focus = true, }) +end, { silent = true }) -- also update the root with the bang + +vim.keymap.set('n', 'ia', 'gg=Gzz') +vim.keymap.set('n', 'ya', 'ggVG"+y') + +vim.keymap.set('n', 'ss', ':wa') +vim.keymap.set('n', 'sw', function() + local word = vim.fn.expand("") + local replacement = vim.fn.input("Replace '" .. word .. "' with: ") + if replacement ~= "" then + vim.cmd(string.format("%%s/\\<%s\\>/%s/gI", vim.fn.escape(word, '\\/'), vim.fn.escape(replacement, '\\/'))) + end +end, { desc = "Substitute word under cursor (prompt)" }) +vim.keymap.set('v', 'sv', function() + -- Save the current selection + local save_reg = vim.fn.getreg('"') + local save_regtype = vim.fn.getregtype('"') + + -- Yank the visual selection into the " register + vim.cmd('normal! ""y') + + local selection = vim.fn.getreg('"') + -- Escape magic characters for the search + selection = vim.fn.escape(selection, '\\/.*$^~[]') + + -- Prompt for the replacement text + local replacement = vim.fn.input("Replace '" .. selection .. "' with: ") + if replacement ~= "" then + vim.cmd(string.format("%%s/%s/%s/gI", selection, replacement)) + end + + -- Restore previous register + vim.fn.setreg('"', save_reg, save_regtype) +end, { desc = "Substitute selection in file" }) + +vim.keymap.set('n', 'pp', function() + vim.api.nvim_command('normal! "+p') +end, { desc = 'Paste from system clipboard' }) + vim.keymap.set('v', 'p', function() vim.cmd('normal! "+p') end, { desc = 'Yank to clipboard and keep the selection' }) --- branching depeding on diff mode -if vim.g.diffm then - -- diff view commands - vim.keymap.set('n', 'do', ":DiffviewClose:DiffviewOpen") - vim.keymap.set('n', 'df', ":DiffviewClose:DiffviewFileHistory") - vim.keymap.set('n', 'dt', ":DiffviewToggleFiles") - vim.keymap.set('n', 'dc', ":DiffviewClose") - vim.keymap.set('n', 'dl', ":DiffviewLog") - - -- vim.keymap.set("n", "e", "ww") -else - -- not in diff mode - -- TODO: make this dynamic - local season = "S2" - - local links = require("helpers.linker") -- replace with real file path - local user = vim.fn.system('whoami'):gsub('\n', '') - local api = require("nvim-tree.api") - local builtin = require('telescope.builtin') - local current_date = os.date("%Y-%m-%d") - local week_number = os.date("%W") + 1 -- Week number (starting from Sunday) - local day_of_week = os.date("%a") -- Abbreviated weekday name (e.g., Mon, Tue) - - -- this is how to access global vars - function set_obs() - -- _G is the global table. this creates variable 'obs' attached to - -- the global table with the value 'some text value' - _G.season = season - end +vim.keymap.set('n', 'fr', function() + require('telescope.builtin').oldfiles({ + disable_devicons = true, + }) +end, { noremap = true, silent = true }) +vim.keymap.set('n', 'fb', builtin.buffers, { desc = 'Telescope buffers' }) +vim.keymap.set('n', 'fh', builtin.help_tags, { desc = 'Telescope help tags' }) +vim.keymap.set("n", "fl", links.follow_link, { desc = "Follow Link" }) - --------------------- NORMAL ------------------------- - +vim.keymap.set('n', 'g', function() + require('telescope.builtin').live_grep({ + disable_devicons = true, + cwd = vim.fn.getcwd(), -- set the starting directory + additional_args = function() + return { '--hidden', '--glob', '!.git/*' } -- include hidden files but exclude .git + end, + }) +end, { noremap = true, silent = true }) - -- vim.keymap.set("i", "", "", { silent = true }) +vim.keymap.set('n', '', find_eff, + { desc = 'Telescope find files (with dotfiles and folders but excluding .git, .cache, .local, and large files)' }) + +------------------------ VISUAL ------------------ + +vim.keymap.set('v', 'p', function() + local unnamed_content = vim.fn.getreg('""') + vim.api.nvim_command('normal! p') + vim.fn.setreg('""', unnamed_content) +end, { desc = 'Paste from unnamed register (don\'t overwrite it) in visual mode' }) +vim.keymap.set('v', 'y', function() + vim.cmd('normal! "+y') + vim.cmd('normal! gv') +end, { desc = 'Yank to clipboard and keep the selection' }) - vim.keymap.set("n", "L", ":BufferNext", { silent = true }) -- also update the root with the bang - vim.keymap.set("n", "n", "nzz", { silent = true }) -- also update the root with the bang - vim.keymap.set("n", "N", "Nzz", { silent = true }) -- also update the root with the bang - vim.keymap.set("n", "H", ":BufferPrevious", { silent = true }) -- also update the root with the bang - vim.keymap.set("n", "", "zz", { silent = true }) -- also update the root with the bang - vim.keymap.set("n", "", "zz", { silent = true }) -- also update the root with the bang - vim.keymap.set("n", "", "zz", { silent = true }) -- also update the root with the bang - vim.keymap.set("n", "", "zz", { silent = true }) -- also update the root with the bang +---------------------------- INSERT --------------------------- - vim.keymap.set('n', 'a', 'm9ggVG"+y`9') - vim.keymap.set('n', 'va', 'ggVG') - - -- Launch panel if nothing is typed after z - vim.keymap.set("n", "z", "Telekasten panel") - - -- Most used functions - vim.keymap.set("n", "zf", "Telekasten find_notes") - vim.keymap.set("n", "zg", "Telekasten search_notes") - vim.keymap.set('n', 'zq', ':e ~/synced/brainstore/zettelkasten/input.txt`.zz') - vim.keymap.set("n", "zd", "Telekasten goto_today") - vim.keymap.set("n", "zr", "Telekasten rename_note") - vim.keymap.set("n", "zz", "Telekasten follow_link") - vim.keymap.set("n", "zn", "Telekasten new_note") - vim.keymap.set("n", "zb", "Telekasten show_backlinks") - vim.keymap.set("n", "zw", "Telekasten find_weekly_notes") - vim.keymap.set("n", "zI", "Telekasten insert_img_link") - - vim.keymap.set("n", "me", ":mes") - vim.keymap.set("n", "", ":ToggleTerm") - vim.keymap.set("t", "", ":ToggleTerm") - - vim.keymap.set("n", "snt", "set nu") - vim.keymap.set("n", "snf", "set nonu") - - - -- Call insert link automatically when we start typing a link - vim.keymap.set("n", "il", "Telekasten insert_link") - - require("custom.uni") - vim.keymap.set("n", "nv", function() - - select_course_directory() - --pick_unicourse("/home/jonas/projects/university/S2") -- Change path accordingly - end, { desc = "Open UniCourse menu" }) - - - vim.keymap.set('n', 'ca', 'ggVGd') - vim.keymap.set("n", "bd", ":BufferDelete", { silent = true }) -- also update the root with the bang - - -- Typstar stuff - vim.keymap.set("n", "ti", ":TypstarInsertRnote", { silent = true }) -- also update the root with the bang - vim.keymap.set("n", "to", ":TypstarOpenDrawing", { silent = true }) -- also update the root with the bang - - - -- Get a ready to use terminal - vim.keymap.set('n', 'tr', ':tabnew:termi') - vim.keymap.set("n", "tt", ":Telescope", { desc = "Follow Link" }) - vim.keymap.set('n', 'tw', watch_and_open, { noremap = true, silent = true }) - - -- This needs to be refined for quick access to a new file or a recently edited one - vim.keymap.set('n', 'ov', open_vorlesung) - -- new quick note file - -- TODO: make this smarter - vim.keymap.set("n", "nn", ":e ~/synced/brainstore/zettelkasten/quick", { silent = true }) -- also update the root with the bang - - vim.keymap.set("n", "r", set_root) - - -- Custom journal plugin disable temporary - -- local journal = require("custom.journal") - -- vim.keymap.set("n", "jt", journal.open_today, { desc = "Open Today's Journal" }) - -- vim.keymap.set("n", "ja", journal.list_all_journals, { desc = "Open Today's Journal" }) - -- vim.keymap.set("n", "jm", journal.search_this_month, { desc = "Search This Month's Journals" }) - - -- Quickly open some buffers - -- Open all the vim configs instant - vim.keymap.set('n', 'occ', ':e ~/.config/nvim/init.lua`.zz') - vim.keymap.set('n', 'oct', ':e ~/synced/vault/contacts/contacts.txt`.zz') - vim.keymap.set('n', 'ock', ':e ~/.config/nvim/lua/config/keymaps.lua`.zz') - vim.keymap.set('n', 'ocd', ':e ~/.config/nvim/lua/config/autocmds.lua`.zz') - vim.keymap.set('n', 'oco', ':e ~/.config/nvim/lua/config/options.lua`.zz') - vim.keymap.set('n', 'ocl', ':e ~/.config/nvim/lua/config/lazy.lua`.zz') - vim.keymap.set('n', 'oczl', ':e ~/.config/nvim/lua/config/lsp.lua`.zz') - vim.keymap.set('n', 'ocp', ':e ~/.config/nvim/lua/plugins/main.lua`.zz') - vim.keymap.set('n', 'ocf', ':e ~/.config/nvim/lua/helpers/functions.lua`.zz') - vim.keymap.set('n', 'oca', ':e ~/.config/nvim/lua/helpers/after.lua`.zz') - vim.keymap.set('n', 'oq', ':e ~/synced/brainstore/input.txt`.zz') - vim.keymap.set('n', 'ohh', ':e ~/configuration/nixos/users/' .. user .. '/home.nix`.zz') - vim.keymap.set('n', 'op', ':e ~/configuration/nixos/users/' .. user .. '/packages.nix`.zz') - vim.keymap.set('n', 'on', ':e ~/configuration/nixos/configuration.nix`.zz') - vim.keymap.set('n', 'om', ':e ~/configuration/nixos/modules') - vim.keymap.set('n', 'ow', ':e ~/synced/brainstore/waste.txt') - vim.keymap.set('n', 'oho', ':e ~/configuration/nixos/hosts') - vim.keymap.set('n', 'os', ':e ~/configuration/nixos/modules/server') - vim.keymap.set('n', 'ot', ':e ~/synced/brainstore/todos/todo.txt`.zz') - vim.keymap.set('n', 'od', ':e ~/synced/brainstore/todos/done.txt`.zz') - vim.keymap.set('n', 'ou', ':e ~/projects/university/' .. season .. '/input.txt`.zz') - vim.keymap.set('n', 'oz', ':e ~/.zshrc`.zz') - vim.keymap.set('n', 'oaa', ':e ~/.common_shell`.zz') - -- Map the function to a keybinding (e.g., lf to open the last file) - vim.keymap.set("n", "or", "lua open_last_file()", { noremap = true, silent = true }) - -- open the calendar - -- - function open_cal() - local current_date = os.date("%Y-%m-%d") - local week_number = os.date("%V") - local day_of_week = os.date("%a") - local path = "~/synced/brainstore/calendar/calendar_" .. os.date("%Y") .. ".txt" - local keys = ":e " .. path .. "/" .. current_date .. " w" .. tonumber(week_number) .. " " .. day_of_week .. "$" - vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), 'n', true) - end - - vim.keymap.set('n', 'ok', open_cal) - ------------------------------------------------------------------------------------- - - vim.keymap.set("n", "lf", links.insert_brainstore_link, { desc = "Link Brainstore file" }) - vim.keymap.set("n", "lm", links.insert_mail_link, { desc = "Link Mail" }) - vim.keymap.set('n', 'll', ':Lazy') - vim.keymap.set("n", "lp", links.insert_project_link, { desc = "Link Project" }) - vim.keymap.set("n", "lc", links.insert_contact_link, { desc = "Link Contact" }) - vim.keymap.set("n", "ld", links.insert_date_link, { desc = "Link Contact" }) - - - -- nvim tree - vim.keymap.set("n", "e", function() - api.tree.toggle({ find_file = true, update_root = true, focus = true, }) - - end, { silent = true }) -- also update the root with the bang - - vim.keymap.set('n', 'ia', 'gg=Gzz') - vim.keymap.set('n', 'ya', 'ggVG"+y') - - -- Map q to save and quit all buffers with error handling - -- Dangerous but feels good - - vim.keymap.set('n', 'ss', ':wa') - vim.keymap.set('n', 'sw', function() - local word = vim.fn.expand("") - local replacement = vim.fn.input("Replace '" .. word .. "' with: ") - if replacement ~= "" then - vim.cmd(string.format("%%s/\\<%s\\>/%s/gI", vim.fn.escape(word, '\\/'), vim.fn.escape(replacement, '\\/'))) +vim.keymap.set('i', '', function() + local col = vim.fn.col('.') + local line = vim.fn.line('.') + local line_len = vim.fn.col('$') - 1 + if col <= line_len then + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('', true, false, true), 'n', true) + else + if line < vim.fn.line('$') then + vim.cmd('normal! j^') end - end, { desc = "Substitute word under cursor (prompt)" }) - vim.keymap.set('v', 'sv', function() - -- Save the current selection - local save_reg = vim.fn.getreg('"') - local save_regtype = vim.fn.getregtype('"') - - -- Yank the visual selection into the " register - vim.cmd('normal! ""y') - - local selection = vim.fn.getreg('"') - -- Escape magic characters for the search - selection = vim.fn.escape(selection, '\\/.*$^~[]') - - -- Prompt for the replacement text - local replacement = vim.fn.input("Replace '" .. selection .. "' with: ") - if replacement ~= "" then - vim.cmd(string.format("%%s/%s/%s/gI", selection, replacement)) - end - - -- Restore previous register - vim.fn.setreg('"', save_reg, save_regtype) - end, { desc = "Substitute selection in file" }) - -- vim.keymap.set('n', 'sl', search_brain_links) - - vim.keymap.set('n', 'pp', function() - vim.api.nvim_command('normal! "+p') - end, { desc = 'Paste from system clipboard' }) - - -- vim.keymap.set('n', 'fg', builtin.live_grep, { desc = 'Telescope live grep' }) - vim.keymap.set('n', 'fr', function() - require('telescope.builtin').oldfiles({ - disable_devicons = true, - }) - end, { noremap = true, silent = true }) - vim.keymap.set('n', 'fb', builtin.buffers, { desc = 'Telescope buffers' }) - vim.keymap.set('n', 'fh', builtin.help_tags, { desc = 'Telescope help tags' }) - vim.keymap.set("n", "fl", links.follow_link, { desc = "Follow Link" }) - - - vim.keymap.set('n', 'g', function() - require('telescope.builtin').live_grep({ - disable_devicons = true, - cwd = vim.fn.getcwd(), -- set the starting directory - additional_args = function() - return { '--hidden', '--glob', '!.git/*' } -- include hidden files but exclude .git - end, - }) - end, { noremap = true, silent = true }) - - vim.keymap.set('n', '', find_eff, { desc = 'Telescope find files (with dotfiles and folders but excluding .git, .cache, .local, and large files)' }) - - ------------------------ VISUAL ------------------ - - vim.keymap.set('v', 'p', function() - local unnamed_content = vim.fn.getreg('""') - vim.api.nvim_command('normal! p') - vim.fn.setreg('""', unnamed_content) - end, { desc = 'Paste from unnamed register (don\'t overwrite it) in visual mode' }) - vim.keymap.set('v', 'y', function() - vim.cmd('normal! "+y') - vim.cmd('normal! gv') - end, { desc = 'Yank to clipboard and keep the selection' }) - - - ---------------------------- INSERT --------------------------- - - vim.keymap.set('i', '', function() - local col = vim.fn.col('.') - local line = vim.fn.line('.') - local line_len = vim.fn.col('$') - 1 - if col <= line_len then + end +end) +-- Move left with wrapping +vim.keymap.set('i', '', function() + local col = vim.fn.col('.') + local line = vim.fn.line('.') + if col > vim.fn.indent(line) + 1 then + -- not at very beginning (after indent), move left + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('', true, false, true), 'n', true) + else + if line > 1 then + vim.cmd('normal! k$') vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('', true, false, true), 'n', true) - else - if line < vim.fn.line('$') then - vim.cmd('normal! j^') - end end - end) - -- Move left with wrapping - vim.keymap.set('i', '', function() - local col = vim.fn.col('.') - local line = vim.fn.line('.') - if col > vim.fn.indent(line) + 1 then - -- not at very beginning (after indent), move left - vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('', true, false, true), 'n', true) - else - if line > 1 then - vim.cmd('normal! k$') - vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('', true, false, true), 'n', true) - end - end - end, { noremap = true, silent = true }) -end - + end +end, { noremap = true, silent = true }) diff --git a/lua/config/lazy.lua b/lua/config/lazy.lua index 89a7003..435c984 100644 --- a/lua/config/lazy.lua +++ b/lua/config/lazy.lua @@ -1,4 +1,4 @@ --- Bootstrap lazy.nvim +-- Bootstrap lazy manager first thing local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not (vim.uv or vim.loop).fs_stat(lazypath) then local lazyrepo = "https://github.com/folke/lazy.nvim.git" @@ -6,7 +6,7 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then if vim.v.shell_error ~= 0 then vim.api.nvim_echo({ { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, - { out, "WarningMsg" }, + { out, "WarningMsg" }, { "\nPress any key to exit..." }, }, true, {}) vim.fn.getchar() @@ -15,34 +15,22 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then end vim.opt.rtp:prepend(lazypath) --- Make sure to setup `mapleader` and `maplocalleader` before --- loading lazy.nvim so that mappings are correct. --- This is also a good place to setup other settings (vim.opt) +-- Must load before lazy vim.g.mapleader = " " vim.g.maplocalleader = "\\" --- Setup lazy.nvim require("lazy").setup({ spec = { - -- import your plugins - -- { import = "plugins" }, - require("plugins") + -- Import all files in the plugin folder + { import = "plugins" }, }, - -- Configure any other settings here. See the documentation for more details. - -- colorscheme that will be used when installing plugins. - install = { colorscheme = { "gruvbox" } }, - -- automatically check for plugin updates + -- Automatically check for plugin updates checker = { enabled = false }, dev = { path = "~/projects", fallback = true, }, change_detection = { - enabled = false, -- disable automatic reloading - notify = false, -- optional: also disable notification when it would reload + enabled = false, }, }) - --- after lazy did its job -require("helpers.after") - diff --git a/lua/config/lsp.lua b/lua/config/lsp.lua deleted file mode 100644 index 45bd719..0000000 --- a/lua/config/lsp.lua +++ /dev/null @@ -1,109 +0,0 @@ --- lsp.lua -local lspconfig = require("lspconfig") -local cmp = require("cmp") - - -require("lspconfig").clangd.setup({ -}) - - --- nvim-cmp setup -cmp.setup({ - snippet = { - expand = function(args) require("luasnip").lsp_expand(args.body) end, - }, - mapping = cmp.mapping.preset.insert({ - [""] = cmp.mapping.complete(), - [""] = cmp.mapping.confirm({ select = true }), - [""] = cmp.mapping.select_next_item(), - [""] = cmp.mapping.select_prev_item(), - }), - sources = cmp.config.sources({ - { name = "nvim_lsp" }, - { name = "luasnip" }, - }, { - { name = "buffer" }, - { name = "path" }, - }), -}) - --- Capabilities for nvim-cmp -local capabilities = require("cmp_nvim_lsp").default_capabilities() - - --- Example servers -local servers = { "gopls", "pyright", "lua_ls", "rust_analyzer", "clangd" } - - -require("mason-lspconfig").setup({ - ensure_installed = servers -}) -for _, lsp in ipairs(servers) do - local config = { - capabilities = capabilities, - on_attach = function(_, bufnr) - local opts = { buffer = bufnr, noremap = true, silent = true } - - -- LSP core - vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) -- Jump to definition - vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts) -- Jump to declaration - vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) -- Find references - vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) -- Go to implementation - vim.keymap.set("n", "gt", vim.lsp.buf.type_definition, opts) -- Go to type definition - vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) -- Hover docs - vim.keymap.set("n", "", vim.lsp.buf.signature_help, opts) -- Signature help - - -- Refactor - vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) -- Rename symbol - vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) -- Code actions - - -- Diagnostics - vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) -- Previous diagnostic - vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts) -- Next diagnostic - vim.keymap.set("n", "e", vim.diagnostic.open_float, opts) -- Show diagnostic - vim.keymap.set("n", "lq", vim.diagnostic.setloclist, opts) -- List diagnostics - - -- Workspace - vim.keymap.set("n", "wa", vim.lsp.buf.add_workspace_folder, opts) - vim.keymap.set("n", "wr", vim.lsp.buf.remove_workspace_folder, opts) - vim.keymap.set("n", "wl", function() - print(vim.inspect(vim.lsp.buf.list_workspace_folders())) - end, opts) - - -- Formatting - vim.keymap.set("n", "fff", function() - vim.lsp.buf.format({ async = true }) - end, opts) - end - } - if lsp == "lua_ls" then - config.settings = { - Lua = { - diagnostics = { - globals = { "vim" }, - }, - }, - } - end - - if lsp == "clangd" then - config.cmd = { - "clangd", - "--query-driver=/run/current-system/sw/bin/clang", - "--compile-commands-dir=build", - } - end - - lspconfig[lsp].setup(config) -end --- Diagnostic config (inline virtual text + signs + underlines) -vim.diagnostic.config({ - virtual_text = { - prefix = "●", -- could be '●', '▎', 'x' - spacing = 2, - }, - signs = true, - underline = true, - update_in_insert = false, - severity_sort = true, -}) diff --git a/lua/config/options.lua b/lua/config/options.lua index 3a7ba4c..7ff7529 100644 --- a/lua/config/options.lua +++ b/lua/config/options.lua @@ -1,23 +1,18 @@ - --- vim.o.textwidth = 80 --- vim.o.wrap = true; vim.o.shiftwidth = 4; vim.o.tabstop = 4; vim.o.number = true; vim.o.ignorecase = true; -vim.o.mouse= ""; --- this stands for undofile and should be always used because why not? +-- Disable mouse completly +vim.o.mouse = ""; + +-- Turn on undofile vim.o.udf = true; --- optionally enable 24-bit colour +-- Enable more colors vim.opt.termguicolors = true -if vim.g.diffm then - vim.g.loaded_netrw = 0 - vim.g.loaded_netrwPlugin = 0 -else - vim.g.loaded_netrw = 1 - vim.g.loaded_netrwPlugin = 1 -end +vim.g.loaded_netrw = 1 +vim.g.loaded_netrwPlugin = 1 + vim.opt.signcolumn = "yes" diff --git a/lua/custom/journal.lua b/lua/custom/journal.lua index 59ce1a6..b6004f4 100644 --- a/lua/custom/journal.lua +++ b/lua/custom/journal.lua @@ -22,6 +22,9 @@ M.open_today = function() -- If the file does not exist, create and write the header local header = string.format("# Journal Entry - [[date:%s]]\n\n", os.date("%d.%m.%y")) file = io.open(full_path, "w") + if file == nil then + return + end file:write(header) file:close() end diff --git a/lua/custom/todo.lua b/lua/custom/todo/init.lua similarity index 97% rename from lua/custom/todo.lua rename to lua/custom/todo/init.lua index 29b2478..490a080 100644 --- a/lua/custom/todo.lua +++ b/lua/custom/todo/init.lua @@ -22,9 +22,6 @@ function M.remove_priority() vim.api.nvim_set_current_line(line) end -local function strip_ansi(s) - return s:gsub("\27%[[0-9;]*m", "") -end function M.mark_done() if not is_todo_file() then return end diff --git a/lua/custom/typst.lua b/lua/custom/typst.lua new file mode 100644 index 0000000..19a7cf3 --- /dev/null +++ b/lua/custom/typst.lua @@ -0,0 +1,98 @@ +local functions = require("utils.functions") +local watch_job_id = nil +local watch_buf_id = nil + +local function watch_and_open() + local input = vim.fn.expand("%:p") + if not input:match("%.typ$") then + vim.notify("Not a Typst file", vim.log.levels.WARN) + return + end + + local dir = vim.fn.fnamemodify(input, ":h") -- directory of the Typst file + local filename = vim.fn.expand("%:t:r") .. ".pdf" -- filename without extension + .pdf + + -- Get the underlying unicourse dir + local one_up = vim.fn.fnamemodify(dir, ":h") + + print(one_up) + local pdf_dir = nil + if vim.fn.filereadable(one_up .. "/.unicourse") == 1 then + pdf_dir = one_up .. "/../../pdfs" + else + pdf_dir = dir + end + + vim.fn.mkdir(pdf_dir, "p") + local output = pdf_dir .. "/" .. filename + + -- Check if a watcher is already running for this file + if watch_job_id then + vim.notify("Typst watcher already running - please close zathura", vim.log.levels.INFO) + return + end + + + + -- Start typst watch + local cwd = vim.fn.getcwd() -- set the starting directory + -- TODO: root setting does not work + local watch_cmd = { "typst", "watch", "--root", cwd, input, output } + watch_job_id = vim.fn.jobstart(watch_cmd, { + stdout_buffered = false, + stderr_buffered = false, -- Ensure stderr is unbuffered for real-time error output + on_stderr = function(_, data) + if data then + if not watch_tab_id then + pre_tab = vim.api.nvim_get_current_tabpage() -- Get the current tab ID + vim.cmd('tabnew') -- Open a new tab + watch_tab_id = vim.api.nvim_get_current_tabpage() -- Get the current tab ID + watch_buf_id = vim.api.nvim_get_current_buf() -- Get the buffer ID of the new tab + vim.api.nvim_buf_set_option(watch_buf_id, "swapfile", false) + vim.api.nvim_buf_set_name(watch_buf_id, "/tmp/TypstLog") + vim.api.nvim_buf_set_lines(watch_buf_id, 0, 0, false, { "Watching: " .. input }) -- Insert at the top + vim.cmd('write!') + vim.api.nvim_set_current_tabpage(pre_tab) + end + -- Write stdout data to the same buffer + for _, line in ipairs(data) do + if line ~= "" then + vim.api.nvim_buf_set_lines(watch_buf_id, -1, -1, false, { "[LOG] " .. line }) + end + end + end + end, + on_exit = function(_, exit_code) + -- Ensure to close the tab that holds the logs + --if watch_tab_id then + -- -- Switch to the tab holding the log buffer and close it + -- vim.api.nvim_set_current_tabpage(watch_tab_id) + -- vim.cmd('tabclose') -- Close the tab holding the log buffer + --end + if exit_code == 0 then + vim.notify("Typst watch stopped successfully", vim.log.levels.INFO) + else + vim.notify("Typst watch stopped with errors", vim.log.levels.ERROR) + end + watch_job_id = nil + end, + }) + vim.notify("Started Typst watch", vim.log.levels.INFO) + + -- Start sioyek with the --new-window flag and stop watch when it exits + -- ensure that there is no sioyek + vim.fn.system("killall .zathura-wrapped") + functions.Sleep(0.5) + vim.fn.jobstart({ "zathura", output }, { + on_exit = function() + if watch_job_id then + vim.fn.jobstop(watch_job_id) + end + watch_job_id = nil + end, + }) +end + +return { + Watch_and_open = watch_and_open +} diff --git a/lua/custom/uni.lua b/lua/custom/uni.lua index 9d57ee2..d3a55e3 100644 --- a/lua/custom/uni.lua +++ b/lua/custom/uni.lua @@ -1,151 +1,149 @@ local fzf = require("fzf-lua") local fn = vim.fn -local uv = vim.loop local current_season = "S3" -- Function to scan for .unicourse files and get their course directories function get_course_directories() - local dirs = {} - local function scan_dir(dir) - for _, entry in ipairs(fn.glob(dir .. "/*", true, true)) do - if fn.isdirectory(entry) == 1 then - local unicourse_file = entry .. "/.unicourse" - if fn.filereadable(unicourse_file) == 1 then - local course_info = {} - for line in io.lines(unicourse_file) do - if line:match("^name: ") then - course_info.name = line:sub(7) - elseif line:match("^short: ") then - course_info.short = line:sub(8) - end - end - if course_info.name and course_info.short then - table.insert(dirs, { name = course_info.name, short = course_info.short, path = entry }) - end - end - end - end - end + local dirs = {} + local function scan_dir(dir) + for _, entry in ipairs(fn.glob(dir .. "/*", true, true)) do + if fn.isdirectory(entry) == 1 then + local unicourse_file = entry .. "/.unicourse" + if fn.filereadable(unicourse_file) == 1 then + local course_info = {} + for line in io.lines(unicourse_file) do + if line:match("^name: ") then + course_info.name = line:sub(7) + elseif line:match("^short: ") then + course_info.short = line:sub(8) + end + end + if course_info.name and course_info.short then + table.insert(dirs, { name = course_info.name, short = course_info.short, path = entry }) + end + end + end + end + end - scan_dir("/home/jonas/projects/university/" .. current_season) -- Assuming all your courses are under the S2 folder - return dirs + scan_dir("/home/jonas/projects/university/" .. current_season) -- Assuming all your courses are under the S2 folder + return dirs end -- Function to show the fzf menu for selecting a course directory function select_course_directory() - local courses = get_course_directories() - local course_names = {} + local courses = get_course_directories() + local course_names = {} - for _, course in ipairs(courses) do - table.insert(course_names, course.name .. " (" .. course.short .. ")") - end + for _, course in ipairs(courses) do + table.insert(course_names, course.name .. " (" .. course.short .. ")") + end - fzf.fzf_exec(course_names, { - prompt = "Select a course > ", - actions = { - ["default"] = function(selected) - for _, course in ipairs(courses) do - if selected[1] == (course.name .. " (" .. course.short .. ")") then - show_course_menu(course) - break - end - end - end, - }, - }) + fzf.fzf_exec(course_names, { + prompt = "Select a course > ", + actions = { + ["default"] = function(selected) + for _, course in ipairs(courses) do + if selected[1] == (course.name .. " (" .. course.short .. ")") then + show_course_menu(course) + break + end + end + end, + }, + }) end -- Function to show the fzf menu for actions on a selected course folder function show_course_menu(course) - local files = {} - -- Collect all VL files in the Vorlesungen directory - for _, file in ipairs(fn.glob(course.path .. "/VL/*", true, true)) do - if file:match("%.typ$") then - table.insert(files, file) - end - end + local files = {} + -- Collect all VL files in the Vorlesungen directory + for _, file in ipairs(fn.glob(course.path .. "/VL/*", true, true)) do + if file:match("%.typ$") then + table.insert(files, file) + end + end - -- Collect options + -- Collect options -- TODO: implement zettel (Hausaufgaben) management -- For example creation of new ones and quick opening of the pdfs - local options = { - "Open the newest VL file", - "Create a new VL", - "Open the course folder", - "Open a specific file", - } + local options = { + "Open the newest VL file", + "Create a new VL", + "Open the course folder", + "Open a specific file", + } - fzf.fzf_exec(options, { - prompt = "Choose an action > ", - actions = { - ["default"] = function(selected) - if selected[1] == "Open the newest VL file" then - local newest_file = get_newest_vl_file(files) - vim.cmd("edit " .. newest_file) - elseif selected[1] == "Create a new VL" then - create_new_vl(course) - elseif selected[1] == "Open the course folder" then - vim.cmd("edit " .. course.path) - elseif selected[1] == "Open a specific file" then - fzf.fzf_exec(fn.glob(course.path .. "/*", true, true), { - prompt = "Pick a file to open > ", - actions = { - ["default"] = function(file) - vim.cmd("edit " .. file[1]) - end, - }, - }) - end - end, - }, - }) + fzf.fzf_exec(options, { + prompt = "Choose an action > ", + actions = { + ["default"] = function(selected) + if selected[1] == "Open the newest VL file" then + local newest_file = get_newest_vl_file(files) + vim.cmd("edit " .. newest_file) + elseif selected[1] == "Create a new VL" then + create_new_vl(course) + elseif selected[1] == "Open the course folder" then + vim.cmd("edit " .. course.path) + elseif selected[1] == "Open a specific file" then + fzf.fzf_exec(fn.glob(course.path .. "/*", true, true), { + prompt = "Pick a file to open > ", + actions = { + ["default"] = function(file) + vim.cmd("edit " .. file[1]) + end, + }, + }) + end + end, + }, + }) end -- Function to get the newest VL file based on modification time function get_newest_vl_file(files) - local newest_file = nil - local newest_time = 0 - for _, file in ipairs(files) do - local stat = fn.getftime(file) - if stat > newest_time then - newest_time = stat - newest_file = file - end - end - return newest_file + local newest_file = nil + local newest_time = 0 + for _, file in ipairs(files) do + local stat = fn.getftime(file) + if stat > newest_time then + newest_time = stat + newest_file = file + end + end + return newest_file end -- Function to create a new VL file based on the template and incrementing the number function create_new_vl(course) - local vl_dir = course.path .. "/VL" + local vl_dir = course.path .. "/VL" local success, _ = pcall(function() vim.fn.mkdir(vl_dir) end) -- Hard coded this - local template_path = vim.fn.expand("~/projects/university/data/template.typ") - if fn.filereadable(template_path) == 1 then - -- Find the latest VL number in the folder - local latest_num = 0 - for _, file in ipairs(fn.glob(vl_dir .. "/*", true, true)) do - if file:match(course.short .. "VL(%d+).typ$") then - local num = tonumber(file:match(course.short .. "VL(%d+).typ$")) - if num > latest_num then - latest_num = num - end - end - end + local template_path = vim.fn.expand("~/projects/university/data/template.typ") + if fn.filereadable(template_path) == 1 then + -- Find the latest VL number in the folder + local latest_num = 0 + for _, file in ipairs(fn.glob(vl_dir .. "/*", true, true)) do + if file:match(course.short .. "VL(%d+).typ$") then + local num = tonumber(file:match(course.short .. "VL(%d+).typ$")) + if num > latest_num then + latest_num = num + end + end + end - -- Create new VL file with incremented number - local new_vl_name = string.format("%sVL%d.typ", course.short, latest_num + 1) - local new_vl_path = vl_dir .. "/" .. new_vl_name + -- Create new VL file with incremented number + local new_vl_name = string.format("%sVL%d.typ", course.short, latest_num + 1) + local new_vl_path = vl_dir .. "/" .. new_vl_name - -- Copy the template if it exists - vim.fn.system({"cp", template_path, new_vl_path}) + -- Copy the template if it exists + vim.fn.system({ "cp", template_path, new_vl_path }) - -- Open the new VL file - vim.cmd("edit " .. new_vl_path) - else - print("Template file (template.typ) not found!") - end + -- Open the new VL file + vim.cmd("edit " .. new_vl_path) + else + print("Template file (template.typ) not found!") + end end - diff --git a/lua/helpers/after.lua b/lua/helpers/after.lua deleted file mode 100644 index c060be0..0000000 --- a/lua/helpers/after.lua +++ /dev/null @@ -1,247 +0,0 @@ --- Disable lsp stuff --- xzl --- setup mason --- xzl ---require("mason").setup() ---require("mason-lspconfig").setup({ --- ensure_installed = { "rust_analyzer", "pyright" }, -- Example LSPs ---}) - --- Example: Configure a server --- TODO: this has to be done better and automatically ---local lspconfig = require("lspconfig") ---lspconfig.rust_analyzer.setup({}) ---lspconfig.pyright.setup({}) - - -if vim.g.diffm then - -- setup tree - require("nvim-tree").setup({ - sort_by = "case_sensitive", - view = { - width = 35, - }, - disable_netrw = false, - }) -else - -- stuff for only main - require 'telescope'.setup { - extensions = { - }, - } - - -- load custom todo plugin - require("custom.todo").setup() - - - -- configure a workflow that integrates image support in documents and a quick opening of them - local base_zet = "~/synced/brainstore/zettelkasten" - require('telekasten').setup({ - home = vim.fn.expand(base_zet), -- Put the name of your notes directory here - dailies = vim.fn.expand(base_zet .. "/daily"), - -- how to change the defualt media folder? - image_subdir = vim.fn.expand(base_zet .. "/media"), - weeklies = vim.fn.expand(base_zet .. "/weekly"), - templates = vim.fn.expand(base_zet .. "/templates"), - template_new_note = vim.fn.expand(base_zet .. "/templates/note.md"), - template_new_daily = vim.fn.expand(base_zet .. "/templates/daily.md"), - template_new_weekly = vim.fn.expand(base_zet .. "/templates/weekly.md"), - - -- auto_set_filetype = false, - -- Important part: - filename_format = "%Y%m%d%H%M-%title%", -- This adds the timestamp + slugged title - new_note_filename = "uuid-title", -- Set naming convention to use uuid first - uuid_type = "%Y%m%d%H%M", -- Timestamp as UUID - uuid_separator = "-", - }) - - -- setup tree - require("nvim-tree").setup({ - sort_by = "case_sensitive", - -- open_on_tab = true, - - view = { - width = 35, - side = "right", - preserve_window_proportions = true, - number = false, - relativenumber = false, - }, - update_focused_file = { - enable = false, - }, - - renderer = { - group_empty = true, - highlight_git = true, - highlight_opened_files = "name", - indent_markers = { - enable = true, - }, - icons = { - show = { - file = false, - folder = false, - folder_arrow = true, - git = false, - modified = false, - hidden = false, - diagnostics = false, - }, - }, - }, - - filters = { - dotfiles = false, -- << SHOW dotfiles by default - git_clean = false, - no_buffer = false, - custom = { ".DS_Store", ".git" }, -- Mac stuff you probably don't need - }, - - git = { - enable = true, - ignore = false, -- so it shows even ignored files - }, - - actions = { - open_file = { - quit_on_open = false, -- keep tree open after opening a file - resize_window = true, - }, - }, - - }) -end - --- stuff for both - --- lualine mode for the current workingdir -local function get_cwd() - local cwd = vim.fn.getcwd() - local home = os.getenv("HOME") - - -- Check if the current directory starts with the home directory path - if cwd:sub(1, #home) == home then - return "~" .. cwd:sub(#home + 1) - else - return cwd - end -end - -require('lualine').setup { - options = { - icons_enabled = false, - theme = 'gruvbox', - -- think those icons are okay - component_separators = { left = '', right = '' }, - section_separators = { left = '', right = '' }, - always_divide_middle = true, - always_show_tabline = true, - globalstatus = false, - refresh = { - statusline = 300, - tabline = 300, - winbar = 300, - } - }, - sections = { - lualine_a = { 'mode' }, - lualine_b = { 'branch', 'diff', 'diagnostics' }, - lualine_c = { get_cwd, 'filename' }, - lualine_x = { 'encoding', 'fileformat', 'filetype' }, - lualine_y = { 'progress' }, - lualine_z = { 'location' } - }, - inactive_sections = { - lualine_a = {}, - lualine_b = {}, - lualine_c = { 'filename' }, - lualine_x = { 'location' }, - lualine_y = {}, - lualine_z = {} - }, - extensions = { "nvim-tree" } -} - - - -require('gitsigns').setup { - on_attach = function(bufnr) - local gitsigns = require('gitsigns') - - local function map(mode, l, r, opts) - opts = opts or {} - opts.buffer = bufnr - vim.keymap.set(mode, l, r, opts) - end - - - map('n', ']c', function() - if vim.wo.diff then - vim.cmd.normal({ ']c', bang = true }) - else - gitsigns.nav_hunk('next') - end - vim.cmd("normal! zz") -- center cursor - end, { silent = true }) - - map('n', '[c', function() - if vim.wo.diff then - vim.cmd.normal({ '[c', bang = true }) - else - gitsigns.nav_hunk('prev') - end - vim.cmd("normal! zz") -- center cursor - end, { silent = true }) - - -- Actions - map('n', 'hs', gitsigns.stage_hunk) - map('n', 'hr', gitsigns.reset_hunk) - - map('v', 'hs', function() - gitsigns.stage_hunk({ vim.fn.line('.'), vim.fn.line('v') }) - end) - - map('v', 'hr', function() - gitsigns.reset_hunk({ vim.fn.line('.'), vim.fn.line('v') }) - end) - - map('n', 'hS', gitsigns.stage_buffer) - map('n', 'hR', gitsigns.reset_buffer) - map('n', 'hp', gitsigns.preview_hunk) - map('n', 'hi', gitsigns.preview_hunk_inline) - - - map('n', 'hb', function() - gitsigns.blame_line({ full = true }) - end) - - map('n', 'hd', gitsigns.diffthis) - - map('n', 'hD', function() - gitsigns.diffthis('~') - end) - - map('n', 'hQ', function() gitsigns.setqflist('all') end) - map('n', 'hq', gitsigns.setqflist) - - -- Toggles - map('n', 'tb', gitsigns.toggle_current_line_blame) - map('n', 'tw', gitsigns.toggle_word_diff) - - -- Text object - map({ 'o', 'x' }, 'ih', gitsigns.select_hunk) - end -} - -require("lspsaga").setup({ - lightbulb = { - enable = false, - enable_in_insert = false, -- don’t show in insert mode - sign = false, - - virtual_text = false, - }, - ui = { - } -}) diff --git a/lua/helpers/functions.lua b/lua/helpers/functions.lua deleted file mode 100644 index 47ff290..0000000 --- a/lua/helpers/functions.lua +++ /dev/null @@ -1,214 +0,0 @@ --- General helper functions - -function sleep(n) - os.execute("sleep " .. tonumber(n)) -end - - --- branching depeding on diff mode -if vim.g.diffm then - -- diffmode -else - -- Function to open NvimTree based on current file or Git root - local api = require("nvim-tree.api") - function open_tree_based_on_file() - local file_path = vim.fn.expand("%:p") - local git_root = vim.fn.system("git rev-parse --show-toplevel"):gsub("\n", "") - local dir = vim.fn.filereadable(file_path) and vim.fn.fnamemodify(file_path, ":p:h") or "" - - -- If inside a Git repo, use the Git root as the base directory - local open_dir = git_root ~= "" and git_root or dir - - -- Open NvimTree in that directory - api.tree.open({ path = open_dir }) - end - - function open_vorlesung() - local mapss = require("config.keymaps") - -- get globals - set_obs() - local uni_dir = vim.fn.expand("~/projects/university/" .. _G.season) - - require('telescope.builtin').find_files { - prompt_title = "Select Vorlesung in " .. _G.season, - cwd = uni_dir, - find_command = { - "eza", "-1", "-D" - }, - } - - end - - -- TODO: fix not putting the pdf in another dir then the current workdir - -- when in a uni folder - -- Open and watch typst - local watch_job_id = nil - local watch_buf_id = nil - function watch_and_open() - local input = vim.fn.expand("%:p") - if not input:match("%.typ$") then - vim.notify("Not a Typst file", vim.log.levels.WARN) - return - end - - local dir = vim.fn.fnamemodify(input, ":h") -- directory of the Typst file - local filename = vim.fn.expand("%:t:r") .. ".pdf" -- filename without extension + .pdf - - -- Get the underlying unicourse dir - local one_up = vim.fn.fnamemodify(dir, ":h") - - print(one_up) - local pdf_dir = nil - if vim.fn.filereadable(one_up .. "/.unicourse") == 1 then - pdf_dir = one_up .. "/../../pdfs" - else - pdf_dir = dir - end - - vim.fn.mkdir(pdf_dir, "p") - local output = pdf_dir .. "/" .. filename - - -- Check if a watcher is already running for this file - if watch_job_id then - vim.notify("Typst watcher already running - please close zathura", vim.log.levels.INFO) - return - end - - - - -- Start typst watch - local cwd = vim.fn.getcwd() -- set the starting directory - -- TODO: root setting does not work - local watch_cmd = { "typst", "watch", "--root", cwd, input, output } - watch_job_id = vim.fn.jobstart(watch_cmd, { - stdout_buffered = false, - stderr_buffered = false, -- Ensure stderr is unbuffered for real-time error output - on_stderr = function(_, data) - if data then - if not watch_tab_id then - pre_tab = vim.api.nvim_get_current_tabpage() -- Get the current tab ID - vim.cmd('tabnew') -- Open a new tab - watch_tab_id = vim.api.nvim_get_current_tabpage() -- Get the current tab ID - watch_buf_id = vim.api.nvim_get_current_buf() -- Get the buffer ID of the new tab - vim.api.nvim_buf_set_option(watch_buf_id, "swapfile", false) - vim.api.nvim_buf_set_name(watch_buf_id, "/tmp/TypstLog") - vim.api.nvim_buf_set_lines(watch_buf_id, 0, 0, false, { "Watching: " .. input }) -- Insert at the top - vim.cmd('write!') - vim.api.nvim_set_current_tabpage(pre_tab) - end - -- Write stdout data to the same buffer - for _, line in ipairs(data) do - if line ~= "" then - vim.api.nvim_buf_set_lines(watch_buf_id, -1, -1, false, { "[LOG] " .. line }) - end - end - end - end, - on_exit = function(_, exit_code) - -- Ensure to close the tab that holds the logs - --if watch_tab_id then - -- -- Switch to the tab holding the log buffer and close it - -- vim.api.nvim_set_current_tabpage(watch_tab_id) - -- vim.cmd('tabclose') -- Close the tab holding the log buffer - --end - if exit_code == 0 then - vim.notify("Typst watch stopped successfully", vim.log.levels.INFO) - else - vim.notify("Typst watch stopped with errors", vim.log.levels.ERROR) - end - watch_job_id = nil - end, - }) - vim.notify("Started Typst watch", vim.log.levels.INFO) - - -- Start sioyek with the --new-window flag and stop watch when it exits - -- ensure that there is no sioyek - vim.fn.system("killall .zathura-wrapped") - sleep(0.5) - vim.fn.jobstart({ "zathura", output }, { - on_exit = function() - if watch_job_id then - vim.fn.jobstop(watch_job_id) - end - watch_job_id = nil - end, - }) - end - -end - - -function find_eff() - require('telescope.builtin').find_files({ - hidden = true, -- show hidden files (dotfiles) - no_ignore = true, -- respect .gitignore (ignore files listed in .gitignore) - follow = true, -- follow symlinks - disable_devicons = true, - - -- Additional filtering to exclude .git, .cache, .local, and large files - prompt_title = "Find Files - custom", - find_command = { - "rg", "--files", - "--glob", "!**/.git/*", - "--glob", "!**/.cache/*", - "--glob", "!**/.local/*", - "--glob", "!**/bigfiles/*", -- exclude large files folder - "--glob", "!**/*.{jpg,png,gif,mp4,mkv,tar,zip,iso}" -- exclude some large file types - } - }) -end - - - --- TODO: implement this ---function search_brain_links() --- local fzf = require('fzf') --- local cmd = "grep -oP '\\[\\[.*:' " .. vim.fn.expand('%') -- grep pattern to search for [[.*: --- fzf.fzf(cmd, { --- preview = "bat --style=numbers --color=always --line-range :500", -- preview with bat (optional) --- sink = function(selected) --- if selected and #selected > 0 then --- local line = vim.fn.search(selected[1], 'n') -- jump to the match --- if line > 0 then --- vim.api.nvim_win_set_cursor(0, {line, 0}) --- end --- end --- end --- }) ---end - - -function set_root() - local current_file = vim.fn.expand('%:p:h') -- get directory of current file - local cmd = 'git -C ' .. vim.fn.fnameescape(current_file) .. ' status' - vim.fn.system(cmd) - if vim.v.shell_error == 0 then - local git_root = vim.fn.systemlist('git -C ' .. vim.fn.fnameescape(current_file) .. ' rev-parse --show-toplevel')[1] - vim.cmd('cd ' .. vim.fn.fnameescape(git_root)) - else - vim.cmd('cd ' .. vim.fn.fnameescape(current_file)) - end -end - - --- Function to open the last file -function open_last_file() - local last_file_path = vim.fn.stdpath('data') .. "/lastfile.txt" - local file = io.open(last_file_path, "r") - if file then - local last_file = file:read("*line") - file:close() - if last_file and vim.fn.filereadable(last_file) == 1 then - vim.cmd("edit " .. last_file) - local success, _ = pcall(function() - vim.cmd('normal! `.') -- Go to the last edit position - vim.cmd('normal! zz') -- Center the cursor on the screen - end) - else - print("Last file does not exist or is not readable") - end - else - print("No last file found") - end -end - diff --git a/lua/plugins/colorscheme.lua b/lua/plugins/colorscheme.lua new file mode 100644 index 0000000..9edd86e --- /dev/null +++ b/lua/plugins/colorscheme.lua @@ -0,0 +1,15 @@ +return { + "ellisonleao/gruvbox.nvim", + + config = function() + -- Useful for terminal emulators with a transparent background + local function transparentBackground() + vim.api.nvim_set_hl(0, "Normal", { bg = "none" }) + vim.api.nvim_set_hl(0, "NormalFloat", { bg = "none" }) + end + + vim.cmd.colorscheme("gruvbox") + + transparentBackground() + end +} diff --git a/lua/plugins/custom.lua b/lua/plugins/custom.lua new file mode 100644 index 0000000..95da755 --- /dev/null +++ b/lua/plugins/custom.lua @@ -0,0 +1,26 @@ +-- Custom modules + +--- @param name string +--- @return string +local function get_dir(name) + return vim.fn.stdpath("config") .. "/lua/custom/" .. name +end + +return { + { + dir = get_dir("todo"), + name = "todo", + dependencies = { "nvim-lua/plenary.nvim", "nvim-telescope/telescope.nvim" }, + config = function() + require("custom.todo").setup() + end, + }, + { + dir = vim.fn.stdpath("config") .. "/lua/custom", -- folder containing typst.lua + name = "typst", + dependencies = { "nvim-lua/plenary.nvim", "nvim-telescope/telescope.nvim" }, + keys = { + { "tw", function() require("custom.typst").Watch_and_open() end, desc = "Watch Typst" }, + }, + }, +} diff --git a/lua/plugins/diff.lua b/lua/plugins/diff.lua deleted file mode 100644 index b39c93a..0000000 --- a/lua/plugins/diff.lua +++ /dev/null @@ -1,27 +0,0 @@ -return { - {"sindrets/diffview.nvim", - dependencies = { - "nvim-lua/plenary.nvim", - "nvim-tree/nvim-web-devicons", - }, - }, - { - -- this is the nvim tree but I dont use it yet - "nvim-tree/nvim-tree.lua", - }, - { - 'nvim-lualine/lualine.nvim', - -- dependencies = { 'nvim-tree/nvim-web-devicons' } - }, - { - "ellisonleao/gruvbox.nvim", - }, - { - "folke/which-key.nvim", - event = "VeryLazy", - opts = { - icons = {mappings = false,}, - delay = 1500, - }, - }, -}; diff --git a/lua/plugins/git.lua b/lua/plugins/git.lua new file mode 100644 index 0000000..d191e72 --- /dev/null +++ b/lua/plugins/git.lua @@ -0,0 +1,92 @@ +return { + { + "kdheepak/lazygit.nvim", + lazy = true, + cmd = { + "LazyGit", + "LazyGitConfig", + "LazyGitCurrentFile", + "LazyGitFilter", + "LazyGitFilterCurrentFile", + }, + dependencies = { + "nvim-lua/plenary.nvim", -- Floating boarders + }, + keys = { + { "lg", "LazyGit", desc = "LazyGit" } + } + }, + { + 'lewis6991/gitsigns.nvim', + config = function() + local gitsigns = require("gitsigns") + + local function on_attach(bufnr) + local function map(mode, l, r, opts) + opts = opts or {} + opts.buffer = bufnr + vim.keymap.set(mode, l, r, opts) + end + + + map('n', ']c', function() + if vim.wo.diff then + vim.cmd.normal({ ']c', bang = true }) + else + gitsigns.nav_hunk('next') + end + vim.cmd("normal! zz") -- center cursor + end, { silent = true }) + + map('n', '[c', function() + if vim.wo.diff then + vim.cmd.normal({ '[c', bang = true }) + else + gitsigns.nav_hunk('prev') + end + vim.cmd("normal! zz") -- center cursor + end, { silent = true }) + + -- Actions + map('n', 'hs', gitsigns.stage_hunk) + map('n', 'hr', gitsigns.reset_hunk) + + map('v', 'hs', function() + gitsigns.stage_hunk({ vim.fn.line('.'), vim.fn.line('v') }) + end) + + map('v', 'hr', function() + gitsigns.reset_hunk({ vim.fn.line('.'), vim.fn.line('v') }) + end) + + map('n', 'hS', gitsigns.stage_buffer) + map('n', 'hR', gitsigns.reset_buffer) + map('n', 'hp', gitsigns.preview_hunk) + map('n', 'hi', gitsigns.preview_hunk_inline) + + + map('n', 'hb', function() + gitsigns.blame_line({ full = true }) + end) + + map('n', 'hd', gitsigns.diffthis) + + map('n', 'hD', function() + gitsigns.diffthis('~') + end) + + map('n', 'hQ', function() gitsigns.setqflist('all') end) + map('n', 'hq', gitsigns.setqflist) + + -- Toggles + map('n', 'tb', gitsigns.toggle_current_line_blame) + map('n', 'tw', gitsigns.toggle_word_diff) + + -- Text object + map({ 'o', 'x' }, 'ih', gitsigns.select_hunk) + end + + gitsigns.setup({ on_attach = on_attach }) + end + } +} diff --git a/lua/plugins/init.lua b/lua/plugins/init.lua deleted file mode 100644 index a4b4e64..0000000 --- a/lua/plugins/init.lua +++ /dev/null @@ -1,9 +0,0 @@ -local plugins = {} - -if vim.g.diffm then - vim.list_extend(plugins, require("plugins.diff")) -else - vim.list_extend(plugins, require("plugins.main")) -end - -return plugins diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua new file mode 100644 index 0000000..4430cc9 --- /dev/null +++ b/lua/plugins/lsp.lua @@ -0,0 +1,123 @@ +return { + { "stevearc/aerial.nvim", opts = {} }, + { + "nvimdev/lspsaga.nvim", + opts = { + lightbulb = { + enable = false, + enable_in_insert = false, + sign = false, + virtual_text = false, + }, + }, + }, + { + "neovim/nvim-lspconfig", + dependencies = { + "williamboman/mason.nvim", + "williamboman/mason-lspconfig.nvim", + + "hrsh7th/nvim-cmp", + "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-buffer", + "nvimdev/lspsaga.nvim", + "hrsh7th/cmp-path", + "L3MON4D3/LuaSnip", + "saadparwaiz1/cmp_luasnip", + }, + config = function() + local lspconfig = require("lspconfig") + + -- Declarative important have npm and other tools installed + local servers = { "gopls", "pyright", "lua_ls", "rust_analyzer", "clangd" } + + -- Custom overwrites for servers + local server_settings = { + lua_ls = { + settings = { + Lua = { + diagnostics = { globals = { "vim" } }, + }, + }, + }, + } + + local cmp = require("cmp") + cmp.setup({ + snippet = { + expand = function(args) require("luasnip").lsp_expand(args.body) end, + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.complete(), + [""] = cmp.mapping.confirm({ select = true }), + [""] = cmp.mapping.select_next_item(), + [""] = cmp.mapping.select_prev_item(), + }), + sources = cmp.config.sources({ + { name = "nvim_lsp" }, + { name = "luasnip" }, + }, { + { name = "buffer" }, + { name = "path" }, + }), + }) + + local capabilities = require("cmp_nvim_lsp").default_capabilities() + + local on_attach = function(_, bufnr) + local opts = { buffer = bufnr, noremap = true, silent = true } + vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) + vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts) + vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) + vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) + vim.keymap.set("n", "gt", vim.lsp.buf.type_definition, opts) + vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) + vim.keymap.set("n", "", vim.lsp.buf.signature_help, opts) + + vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) + vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) + + vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) + vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts) + --vim.keymap.set("n", "e", vim.diagnostic.open_float, opts) + vim.keymap.set("n", "lq", vim.diagnostic.setloclist, opts) + + vim.keymap.set("n", "wa", vim.lsp.buf.add_workspace_folder, opts) + vim.keymap.set("n", "wr", vim.lsp.buf.remove_workspace_folder, opts) + vim.keymap.set("n", "wl", function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, opts) + + vim.keymap.set("n", "ff", function() + vim.lsp.buf.format({ async = true }) + end, opts) + end + + + + -- Setup servers manually + for _, server in ipairs(servers) do + local config = { + capabilities = capabilities, + on_attach = on_attach, + } + if server_settings[server] then + config = vim.tbl_deep_extend("force", config, server_settings[server]) + end + lspconfig[server].setup(config) + end + + -- Mason for autoinstall of servers + require("mason").setup() + require("mason-lspconfig").setup({ + ensure_installed = servers, + automatic_installation = true, + }) + + -- Add text in diagnostics + vim.diagnostic.config({ + virtual_text = true, + }) + end, + }, +} diff --git a/lua/plugins/luasnip.lua b/lua/plugins/luasnip.lua new file mode 100644 index 0000000..4e4e52b --- /dev/null +++ b/lua/plugins/luasnip.lua @@ -0,0 +1,17 @@ +return { + { + "L3MON4D3/LuaSnip", + version = "v2.*", + build = "make install_jsregexp", + event = "InsertEnter", + config = function() + local ls = require("luasnip") + ls.config.setup({ + enable_autosnippets = true, + store_selection_keys = '', + }) + vim.keymap.set({ "i", "s" }, "", function() ls.jump(1) end, { silent = true }) + vim.keymap.set({ "i", "s" }, "", function() ls.jump(-1) end, { silent = true }) + end, + }, +} diff --git a/lua/plugins/main.lua b/lua/plugins/main.lua deleted file mode 100644 index d362890..0000000 --- a/lua/plugins/main.lua +++ /dev/null @@ -1,238 +0,0 @@ -return { - { - "ThePrimeagen/harpoon", - }, - { "akinsho/toggleterm.nvim", config = true }, - { "nvimdev/lspsaga.nvim", config = true }, - { - "kdheepak/lazygit.nvim", - lazy = true, - cmd = { - "LazyGit", - "LazyGitConfig", - "LazyGitCurrentFile", - "LazyGitFilter", - "LazyGitFilterCurrentFile", - }, - -- optional for floating window border decoration - dependencies = { - "nvim-lua/plenary.nvim", - }, - -- setting the keybinding for LazyGit with 'keys' is recommended in - -- order to load the plugin when the command is run for the first time - keys = { - { "lg", "LazyGit", desc = "LazyGit" } - }}, - { - -- treesitter - "nvim-treesitter/nvim-treesitter", - build = ":TSUpdate", - -- prio is needed for this - -- - -- not needed cmd = { "NvimTreeToggle", "NvimTreeOpen" }, -- load only when you call these commands - priority = 1000, - config = function () - local configs = require("nvim-treesitter.configs") - configs.setup({ - ensure_installed = {"css", "typst", "bash", "markdown", "lua", "python", "rust", "c", "nix"}, - sync_install = false, - highlight = { enable = true }, - indent = { enable = true }, - }) - end - }, - { - -- great typstar works only with luasnip - ft = {"typst"}, - "Ascyii/typstar", - dev = true, - config = function() - require("typstar").setup({ - typstarRoot = "~/projects/typstar", - rnote = { - assetsDir = 'assets', - -- can be modified to e.g. export full pages; default is to try to export strokes only and otherwise export the entire document - exportCommand = 'rnote-cli export selection --no-background --no-pattern --on-conflict overwrite --output-file %s all %s || rnote-cli export doc --no-background --no-pattern --on-conflict overwrite --output-file %s %s', - filename = 'drawing-%Y-%m-%d-%H-%M-%S', - fileExtension = '.rnote', - fileExtensionInserted = '.rnote.svg', -- valid rnote export type - uriOpenCommand = 'xdg-open', -- see comment above for excalidraw - templatePath = {}, - }, - }) - end, - }, - {'romgrk/barbar.nvim', - dependencies = { - 'lewis6991/gitsigns.nvim', -- OPTIONAL: for git status - --'nvim-tree/nvim-web-devicons', -- OPTIONAL: for file icons - }, - init = function() vim.g.barbar_auto_setup = false end, - cmd = {"BufferNext", "BufferPrevious" }, - opts = { - clickable = false, - tabpages = false, - animations = false, - icons = { filetype = { enabled = false } } - - }, - version = '^1.0.0', -- optional: only update when a new 1.x version is released - }, - -- Does not work in nvim ? - - -- {"freitass/todo.txt-vim"}, - - -- { - -- 'windwp/nvim-autopairs', - -- enable = false, - -- event = "InsertEnter", - -- config = true - -- -- use opts = {} for passing setup options - -- -- this is equivalent to setup({}) function - -- }, - { - 'nvim-lualine/lualine.nvim', - -- dependencies = { 'nvim-tree/nvim-web-devicons' } - }, - { - "ibhagwan/fzf-lua", - -- optional for icon support - -- dependencies = { "nvim-tree/nvim-web-devicons" }, - -- or if using mini.icons/mini.nvim - -- dependencies = { "echasnovski/mini.icons" }, - opts = {}, - cmd = { "FzfLua" }, -- load when you call :Telekasten - }, - { - -- this is the nvim tree but I dont use it yet - "nvim-tree/nvim-tree.lua", - }, - { - "nvim-telescope/telescope.nvim", tag = '0.1.8', - dependencies = { "nvim-lua/plenary.nvim" }, - }, - { - "ellisonleao/gruvbox.nvim", - }, - -- Will see how this integrates with the existing workflow and what features I can impleemtn by - -- { - -- "nvim-neorg/neorg", - -- lazy = false, -- Disable lazy loading as some `lazy.nvim` distributions set `lazy = true` by default - -- version = "*", -- Pin Neorg to the latest stable release - -- config = true, - -- }, - -- Disable lsp stuff - --{ - -- -- lsp stuff - -- "williamboman/mason.nvim", - -- -- TODO: implement things like rename variables and stuff - -- "williamboman/mason-lspconfig.nvim", - -- "neovim/nvim-lspconfig", - --}, - { - -- LuaSnip configuration - "L3MON4D3/LuaSnip", - version = "v2.*", - build = "make install_jsregexp", - event = "InsertEnter", - config = function() - local ls = require("luasnip") - ls.config.setup({ - enable_autosnippets = true, - store_selection_keys = '', - }) - vim.keymap.set({"i", "s"}, "", function() ls.jump(1) end, {silent = true}) - vim.keymap.set({"i", "s"}, "", function() ls.jump(-1) end, {silent = true}) - end, - }, - -- { - -- "hrsh7th/nvim-cmp", - -- event = "InsertEnter", - -- dependencies = { - -- "hrsh7th/cmp-nvim-lsp", - -- "hrsh7th/cmp-buffer", - -- "hrsh7th/cmp-path", - -- "hrsh7th/cmp-cmdline", - -- "L3MON4D3/LuaSnip", - -- "saadparwaiz1/cmp_luasnip", - -- }, - -- config = function() - -- local cmp = require("cmp") - -- local luasnip = require("luasnip") - -- - -- cmp.setup({ - -- completion = { - -- autocomplete = false, - -- }, - -- snippet = { - -- expand = function(args) - -- require("luasnip").lsp_expand(args.body) - -- end, - -- }, - -- mapping = { - -- [""] = cmp.mapping(function(fallback) - -- if cmp.visible() then - -- cmp.select_next_item() - -- elseif luasnip.expand_or_jumpable() then - -- luasnip.expand_or_jump() - -- else - -- cmp.complete() - -- vim.defer_fn(function() - -- if cmp.visible() then cmp.select_next_item() end - -- end, 10) - -- 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" }), - -- [""] = cmp.mapping.confirm({ select = true }), - -- }, - -- sources = cmp.config.sources({ - -- { name = "nvim_lsp" }, - -- { name = "luasnip" }, - -- }, { - -- { name = "buffer" }, - -- }), - -- }) - -- end, - -- }, - { - 'Ascyii/telekasten.nvim', - dev = true, - }, - { - "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 - icons = {mappings = false,}, - -- set this delay so that its only used for - delay = 1500, - }, - }, - -- LSP support - { "neovim/nvim-lspconfig" }, - { "stevearc/aerial.nvim", opts = {} }, - { "williamboman/mason.nvim", config = true }, - { "williamboman/mason-lspconfig.nvim" }, - - -- Autocompletion - { "hrsh7th/nvim-cmp" }, - { "hrsh7th/cmp-nvim-lsp" }, - { "hrsh7th/cmp-buffer" }, - { "hrsh7th/cmp-path" }, - { "saadparwaiz1/cmp_luasnip" }, - - -- UI improvements - --{ "nvimdev/lspsaga.nvim", config = true }, - --{ "folke/trouble.nvim", opts = {} }, - --{ "j-hui/fidget.nvim", tag = "legacy", config = true }, -}; diff --git a/lua/plugins/misc.lua b/lua/plugins/misc.lua new file mode 100644 index 0000000..28bf47c --- /dev/null +++ b/lua/plugins/misc.lua @@ -0,0 +1,26 @@ +local base_zet = "~/synced/brainstore/zettelkasten" + +return { + { "ThePrimeagen/harpoon" }, + { "akinsho/toggleterm.nvim", config = true }, + { + 'Ascyii/telekasten.nvim', + dev = true, + opts = { + home = vim.fn.expand(base_zet), + dailies = vim.fn.expand(base_zet .. "/daily"), + + image_subdir = vim.fn.expand(base_zet .. "/media"), + weeklies = vim.fn.expand(base_zet .. "/weekly"), + templates = vim.fn.expand(base_zet .. "/templates"), + template_new_note = vim.fn.expand(base_zet .. "/templates/note.md"), + template_new_daily = vim.fn.expand(base_zet .. "/templates/daily.md"), + template_new_weekly = vim.fn.expand(base_zet .. "/templates/weekly.md"), + + filename_format = "%Y%m%d%H%M-%title%", + new_note_filename = "uuid-title", + uuid_type = "%Y%m%d%H%M", + uuid_separator = "-", + } + }, +}; diff --git a/lua/plugins/nvimtree.lua b/lua/plugins/nvimtree.lua new file mode 100644 index 0000000..d6f91e4 --- /dev/null +++ b/lua/plugins/nvimtree.lua @@ -0,0 +1,57 @@ +return { + "nvim-tree/nvim-tree.lua", + opts = { + sort_by = "case_sensitive", + + view = { + width = 35, + side = "right", + preserve_window_proportions = true, + number = false, + relativenumber = false, + }, + update_focused_file = { + enable = false, + }, + + renderer = { + group_empty = true, + highlight_git = true, + highlight_opened_files = "name", + indent_markers = { + enable = true, + }, + icons = { + show = { + file = false, + folder = false, + folder_arrow = true, + git = false, + modified = false, + hidden = false, + diagnostics = false, + }, + }, + }, + + filters = { + dotfiles = false, + git_clean = false, + no_buffer = false, + custom = { ".git" }, + }, + + git = { + enable = true, + ignore = false, + }, + + actions = { + open_file = { + quit_on_open = false, + resize_window = true, + }, + }, + + } +} diff --git a/lua/plugins/searching.lua b/lua/plugins/searching.lua new file mode 100644 index 0000000..3f52a83 --- /dev/null +++ b/lua/plugins/searching.lua @@ -0,0 +1,11 @@ +return { + { + "ibhagwan/fzf-lua", + dependencies = { "nvim-tree/nvim-web-devicons" }, + cmd = { "FzfLua" }, + }, + { + "nvim-telescope/telescope.nvim", + dependencies = { "nvim-lua/plenary.nvim" }, + }, +} diff --git a/lua/plugins/treesitter.lua b/lua/plugins/treesitter.lua new file mode 100644 index 0000000..3120e4f --- /dev/null +++ b/lua/plugins/treesitter.lua @@ -0,0 +1,14 @@ +return { + { + "nvim-treesitter/nvim-treesitter", + build = ":TSUpdate", + priority = 1000, -- Load before everything else + config = function() + local configs = require("nvim-treesitter.configs") + configs.setup({ + sync_install = true, + ensure_installed = { "typst" }, + }) + end + }, +} diff --git a/lua/plugins/typstar.lua b/lua/plugins/typstar.lua new file mode 100644 index 0000000..1c213f0 --- /dev/null +++ b/lua/plugins/typstar.lua @@ -0,0 +1,38 @@ +return { + { + "Ascyii/typstar", + dependencies = { + "L3MON4D3/LuaSnip", + "nvim-treesitter/nvim-treesitter", + }, + dev = true, + ft = { "typst" }, + keys = { + { + "", + "TypstarToggleSnippets", + mode = { "n", "i" }, + }, + { + "", + "TypstarSmartJump", + mode = { "s", "i" }, + }, + { + "", + "TypstarSmartJumpBack", + mode = { "s", "i" }, + }, + }, + config = function() + local typstar = require("typstar") + typstar.setup({ + add_undo_breakpoints = true, + typstarRoot = "~/projects/typstar", + rnote = { + assetsDir = 'typst-assets', + }, + }) + end, + }, +} diff --git a/lua/plugins/ui.lua b/lua/plugins/ui.lua new file mode 100644 index 0000000..bdb0878 --- /dev/null +++ b/lua/plugins/ui.lua @@ -0,0 +1,76 @@ +--- @return string +local function get_cwd() + local cwd = vim.fn.getcwd() + local home = os.getenv("HOME") + + if cwd:sub(1, #home) == home then + return "~" .. cwd:sub(#home + 1) + else + return cwd + end +end + +return { + { + "folke/which-key.nvim", + event = "VeryLazy", + opts = { + icons = { mappings = false, }, + delay = 1500, + }, + }, + { + 'nvim-lualine/lualine.nvim', + dependencies = { 'nvim-tree/nvim-web-devicons' }, + opts = { + options = { + icons_enabled = false, + theme = 'gruvbox', + component_separators = { left = '', right = '' }, + section_separators = { left = '', right = '' }, + always_divide_middle = true, + always_show_tabline = true, + globalstatus = false, + refresh = { + statusline = 300, + tabline = 300, + winbar = 300, + } + }, + sections = { + lualine_a = { 'mode' }, + lualine_b = { 'branch', 'diff', 'diagnostics' }, + lualine_c = { get_cwd, 'filename' }, + lualine_x = { 'encoding', 'fileformat', 'filetype' }, + lualine_y = { 'progress' }, + lualine_z = { 'location' } + }, + inactive_sections = { + lualine_a = {}, + lualine_b = {}, + lualine_c = { 'filename' }, + lualine_x = { 'location' }, + lualine_y = {}, + lualine_z = {} + }, + extensions = { "nvim-tree" } + + } + }, + { + 'romgrk/barbar.nvim', + dependencies = { + 'lewis6991/gitsigns.nvim', + 'nvim-tree/nvim-web-devicons', + }, + init = function() vim.g.barbar_auto_setup = false end, + cmd = { "BufferNext", "BufferPrevious" }, + opts = { + clickable = false, + tabpages = false, + animations = false, + icons = { filetype = { enabled = false } } + }, + version = '^1.0.0', -- only update when a new 1.x version is released + }, +} diff --git a/lua/utils/functions.lua b/lua/utils/functions.lua new file mode 100644 index 0000000..4869abe --- /dev/null +++ b/lua/utils/functions.lua @@ -0,0 +1,98 @@ +-- General helper functions +local M = {} + +function M.Sleep(n) + os.execute("sleep " .. tonumber(n)) +end + +function open_vorlesung() + local mapss = require("config.keymaps") + -- get globals + set_obs() + local uni_dir = vim.fn.expand("~/projects/university/" .. _G.season) + + require('telescope.builtin').find_files { + prompt_title = "Select Vorlesung in " .. _G.season, + cwd = uni_dir, + find_command = { + "eza", "-1", "-D" + }, + } +end + + + +function find_eff() + require('telescope.builtin').find_files({ + hidden = true, -- show hidden files (dotfiles) + no_ignore = true, -- respect .gitignore (ignore files listed in .gitignore) + follow = true, -- follow symlinks + disable_devicons = true, + + -- Additional filtering to exclude .git, .cache, .local, and large files + prompt_title = "Find Files - custom", + find_command = { + "rg", "--files", + "--glob", "!**/.git/*", + "--glob", "!**/.cache/*", + "--glob", "!**/.local/*", + "--glob", "!**/bigfiles/*", -- exclude large files folder + "--glob", "!**/*.{jpg,png,gif,mp4,mkv,tar,zip,iso}" -- exclude some large file types + } + }) +end + +-- TODO: implement this +--function search_brain_links() +-- local fzf = require('fzf') +-- local cmd = "grep -oP '\\[\\[.*:' " .. vim.fn.expand('%') -- grep pattern to search for [[.*: +-- fzf.fzf(cmd, { +-- preview = "bat --style=numbers --color=always --line-range :500", -- preview with bat (optional) +-- sink = function(selected) +-- if selected and #selected > 0 then +-- local line = vim.fn.search(selected[1], 'n') -- jump to the match +-- if line > 0 then +-- vim.api.nvim_win_set_cursor(0, {line, 0}) +-- end +-- end +-- end +-- }) +--end + + +function set_root() + local current_file = vim.fn.expand('%:p:h') -- get directory of current file + local cmd = 'git -C ' .. vim.fn.fnameescape(current_file) .. ' status' + vim.fn.system(cmd) + if vim.v.shell_error == 0 then + local git_root = vim.fn.systemlist('git -C ' .. vim.fn.fnameescape(current_file) .. ' rev-parse --show-toplevel') + [1] + vim.cmd('cd ' .. vim.fn.fnameescape(git_root)) + else + vim.cmd('cd ' .. vim.fn.fnameescape(current_file)) + end +end + +-- Function to open the last file +function open_last_file() + local last_file_path = vim.fn.stdpath('data') .. "/lastfile.txt" + local file = io.open(last_file_path, "r") + if file then + local last_file = file:read("*line") + file:close() + if last_file and vim.fn.filereadable(last_file) == 1 then + vim.cmd("edit " .. last_file) + pcall(function() + vim.cmd('normal! `.') -- Go to the last edit position + vim.cmd('normal! zz') -- Center the cursor on the screen + end) + else + print("Last file does not exist or is not readable") + end + else + print("No last file found") + end +end + + +return M diff --git a/lua/helpers/linker.lua b/lua/utils/linker.lua similarity index 91% rename from lua/helpers/linker.lua rename to lua/utils/linker.lua index 0df3c6c..a24af88 100644 --- a/lua/helpers/linker.lua +++ b/lua/utils/linker.lua @@ -8,7 +8,7 @@ local mail_dir = "~/mail/plain_emails" local contacts_file = "~/synced/vault/contacts/contacts.txt" local cal_dir = "~/synced/brainstore/calendar" -function fzf_select(options, prompt, callback) +local function fzf_select(options, prompt, callback) local fzf = require("fzf-lua") fzf.fzf_exec(options, { prompt = prompt .. "> ", @@ -46,10 +46,10 @@ function M.insert_brainstore_link() end local selected = selection.path or selection.filename or selection[1] if selected then - actions.close(prompt_bufnr) -- CLOSE with prompt_bufnr + actions.close(prompt_bufnr) -- CLOSE with prompt_bufnr local link = "[[brain:" .. selected:gsub(vim.fn.expand(brainstore_dir) .. "/", "") .. "]]" vim.cmd("normal! h") - vim.api.nvim_put({link}, "c", true, true) + vim.api.nvim_put({ link }, "c", true, true) end end @@ -71,7 +71,7 @@ function M.insert_mail_link() fzf_select(mails, "Mails", function(selected) local link = "[[mail:" .. selected:gsub(vim.fn.expand(mail_dir) .. "/", "") .. "]]" - vim.api.nvim_put({link}, "c", true, true) + vim.api.nvim_put({ link }, "c", true, true) end) end @@ -81,7 +81,7 @@ function M.insert_contact_link() fzf_select(contacts, "Contacts", function(selected) local name = selected:match("^(.-)%s") or selected -- get first word as contact name local link = "[[contact:" .. name .. "]]" - vim.api.nvim_put({link}, "c", true, true) + vim.api.nvim_put({ link }, "c", true, true) end) end @@ -129,7 +129,7 @@ function M.insert_project_link() no_ignore = true, follow = true, disable_devicons = true, - prompt_title = "Pick a file. Press to link just " .. project .. ".", + prompt_title = "Pick a file. Press to link just " .. project .. ".", cwd = vim.fn.expand(selected), find_command = { "rg", "--files", @@ -148,15 +148,16 @@ function M.insert_project_link() local selected = selection.path or selection.filename or selection[1] if selected then actions.close(prompt_bufnr) - local link = "[[project:" .. selected:gsub(vim.fn.expand(projects_dir) .. "/", "") .. "]]" - vim.api.nvim_put({link}, "c", true, true) + local link = "[[project:" .. + selected:gsub(vim.fn.expand(projects_dir) .. "/", "") .. "]]" + vim.api.nvim_put({ link }, "c", true, true) end end local function insert_link_top() actions.close(prompt_bufnr) local link = "[[project:" .. project .. "]]" - vim.api.nvim_put({link}, "c", true, true) + vim.api.nvim_put({ link }, "c", true, true) end map('i', '', insert_link) @@ -169,9 +170,6 @@ function M.insert_project_link() return true end }) - - - end end @@ -183,25 +181,24 @@ function M.insert_project_link() }) end - local function spliting(inputstr, sep) if sep == nil then sep = "%s" end local t = {} - for str in string.gmatch(inputstr, "([^"..sep.."]+)") do + for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do table.insert(t, str) end return t end local function pad2(n) - n = tonumber(n) - if n < 10 then - return "0" .. n - else - return tostring(n) - end + n = tonumber(n) + if n < 10 then + return "0" .. n + else + return tostring(n) + end end -- The heart of this project following @@ -253,4 +250,3 @@ function M.follow_link() end return M -