Compare commits

..

17 Commits

Author SHA1 Message Date
1d8aba920c auto up 15:54:41 up 1:28, 2 users, load average: 2.26, 2.48, 1.96 2025-11-18 15:54:43 +01:00
77dee32c29 auto up 09:41:45 up 1:27, 2 users, load average: 0.31, 0.36, 0.36 2025-11-18 09:41:47 +01:00
c4c8ef4893 auto up 11:24:53 up 0:07, 2 users, load average: 2.26, 1.72, 0.89 2025-11-17 11:24:55 +01:00
ea0b19b71a auto up 11:48:23 up 3:25, 2 users, load average: 0.17, 0.26, 0.17 2025-11-14 11:48:39 +01:00
b467a414c4 auto up 14:05:46 up 0:07, 2 users, load average: 0.42, 0.38, 0.20 2025-11-12 14:05:48 +01:00
067c267e26 auto up 17:06:41 up 0:01, 2 users, load average: 0.30, 0.13, 0.05 2025-11-07 17:06:43 +01:00
98bcb5f285 auto up 11:52:14 up 0:59, 2 users, load average: 0.27, 0.30, 0.33 2025-11-06 11:52:15 +01:00
67ee375ba7 auto up 23:53:40 up 0:02, 2 users, load average: 0.88, 0.49, 0.20
auto up  00:24:13  up   0:32,  2 users,  load average: 0.84, 0.77, 0.74

auto up  17:13:21  up   4:51,  2 users,  load average: 1.17, 1.00, 0.87

auto up  18:55:47  up   0:01,  2 users,  load average: 0.67, 0.36, 0.14

auto up  18:57:31  up   0:00,  2 users,  load average: 0.71, 0.18, 0.06

auto up  19:03:28  up   0:09,  2 users,  load average: 0.22, 0.38, 0.26

auto up  01:08:17  up   6:30,  2 users,  load average: 0.62, 0.57, 0.51

auto up  02:38:43  up   0:05,  3 users,  load average: 0.52, 0.53, 0.25

auto up  10:53:19  up   0:00,  2 users,  load average: 1.01, 0.25, 0.08
2025-11-06 10:54:06 +01:00
38f3acc17f Minros 2025-10-03 13:29:45 +02:00
b3cbf4d2c9 Update typstar 2025-09-24 18:56:40 +02:00
ba038af54f Update and fix lsp update deprecation 2025-09-24 18:31:47 +02:00
80bb4e207a Skip usage of windsuf 2025-09-23 16:31:22 +02:00
e4cb69ad82 Fix double lsp 2025-09-18 23:18:19 +02:00
e2a6c21f81 Update readme 2025-09-01 17:07:32 +02:00
c351f5edd4 More lsps 2025-09-01 01:31:42 +02:00
dc95d79a11 Played around with the signcolum 2025-09-01 00:04:10 +02:00
949eb06300 Custom borders for hovering and diagnostics 2025-08-31 16:42:42 +02:00
31 changed files with 2049 additions and 8 deletions

24
LICENSE Normal file
View File

@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>

16
README.md Normal file
View File

@@ -0,0 +1,16 @@
# Neovim configuration in pure lua
Configure the environment in `conf.lua`.
Most lsp require `npm` installed on the system.
## Dependencies
To install proper snippets and get lsp running install the following programs into your path
```
make
curl
gcc
libc
bash
```

View File

@@ -1 +1,3 @@
-- Nvim config by Jonas Hahn
require("config.init")

View File

@@ -1,5 +1,34 @@
{
"LuaSnip": { "branch": "master", "commit": "458560534a73f7f8d7a11a146c801db00b081df0" },
"aerial.nvim": { "branch": "master", "commit": "c7cbbad40c2065fccfd1f1863bb2c08180c0533d" },
"barbar.nvim": { "branch": "master", "commit": "53b5a2f34b68875898f0531032fbf090e3952ad7" },
"cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" },
"cmp-nvim-lsp": { "branch": "main", "commit": "bd5a7d6db125d4654b50eeae9f5217f24bb22fd3" },
"cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" },
"cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
"friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" },
"fzf-lua": { "branch": "main", "commit": "2388dcd61731ae158bf7dad2ae0419291837e557" },
"gitsigns.nvim": { "branch": "main", "commit": "f780609807eca1f783a36a8a31c30a48fbe150c5" },
"gruvbox.nvim": { "branch": "main", "commit": "5e0a460d8e0f7f669c158dedd5f9ae2bcac31437" },
"harpoon": { "branch": "master", "commit": "1bc17e3e42ea3c46b33c0bbad6a880792692a1b3" },
"lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" },
"lazydev.nvim": { "branch": "main", "commit": "258d2a5ef4a3e3d6d9ba9da72c9725c53e9afcbd" },
"lazygit.nvim": { "branch": "main", "commit": "2305deed25bc61b866d5d39189e9105a45cf1cfb" },
"lspsaga.nvim": { "branch": "main", "commit": "8efe00d6aed9db6449969f889170f1a7e43101a1" },
"lualine.nvim": { "branch": "master", "commit": "b8c23159c0161f4b89196f74ee3a6d02cdc3a955" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "a1067cf84b4ff81b66d2bf4d01f4cbdb5de40bd0" },
"mason.nvim": { "branch": "main", "commit": "7dc4facca9702f95353d5a1f87daf23d78e31c2a" },
"nvim-cmp": { "branch": "main", "commit": "b5311ab3ed9c846b585c0c15b7559be131ec4be9" },
"nvim-lspconfig": { "branch": "master", "commit": "b3cce1419ca67871ae782b3e529652f8a016f0de" },
"nvim-tree.lua": { "branch": "master", "commit": "e179ad2f83b5955ab0af653069a493a1828c2697" },
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
"nvim-web-devicons": { "branch": "master", "commit": "6e51ca170563330e063720449c21f43e27ca0bc1" },
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
"telescope.nvim": { "branch": "master", "commit": "b4da76be54691e854d3e0e02c36b0245f945c2c7" }
"telekasten.nvim": { "branch": "main", "commit": "b3ac2b07f2df504bb80112fec349714086a80037" },
"telescope-undo.nvim": { "branch": "main", "commit": "928d0c2dc9606e01e2cc547196f48d2eaecf58e5" },
"telescope.nvim": { "branch": "master", "commit": "b4da76be54691e854d3e0e02c36b0245f945c2c7" },
"toggleterm.nvim": { "branch": "main", "commit": "9a88eae817ef395952e08650b3283726786fb5fb" },
"typstar": { "branch": "main", "commit": "b0613321025cdbd89dbb9ccbc73e62a6b72a80fe" },
"vim-gnupg": { "branch": "main", "commit": "f9b608f29003dfde6450931dc0f495a912973a88" },
"which-key.nvim": { "branch": "main", "commit": "904308e6885bbb7b60714c80ab3daf0c071c1492" }
}

9
lua/conf.lua Normal file
View File

@@ -0,0 +1,9 @@
local config = {}
config.season = "S3" -- Current semester
config.projects = vim.fn.expand("~/projects")
config.uni_dir = vim.fn.expand("~/projects/university/" .. config.season)
config.user = vim.fn.system('whoami'):gsub('\n', '')
config.book_file = vim.fn.expand("~/projects/university/book.typ")
return config

45
lua/config/autocmds.lua Normal file
View File

@@ -0,0 +1,45 @@
-- Save the last file on exit
vim.api.nvim_create_autocmd("VimLeave", {
callback = function()
local last_file = vim.fn.expand('%:p') -- Get the absolute path of the current file
if last_file ~= "" then -- The operator means not equal in lua
local file = io.open(vim.fn.stdpath('data') .. "/lastfile.txt", "w")
if file then
file:write(last_file)
file:close()
end
end
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = "nix",
callback = function()
vim.bo.tabstop = 2
vim.bo.shiftwidth = 2
vim.bo.expandtab = true
end,
})
vim.api.nvim_create_autocmd("FileType", {
pattern = "c",
callback = function()
vim.bo.tabstop = 2
vim.bo.shiftwidth = 2
vim.bo.expandtab = true
end,
})
vim.api.nvim_create_augroup("RememberFolds", {
clear = true
})
vim.api.nvim_create_autocmd({ "BufWinLeave" }, {
group = "RememberFolds",
pattern = "*",
command = "silent! mkview",
})
vim.api.nvim_create_autocmd({ "BufWinEnter" }, {
group = "RememberFolds",
pattern = "*",
command = "silent! loadview",
})

View File

@@ -1 +1,7 @@
-- Load lazy first
require('config.lazy')
-- General settings for nvim
require('config.options')
require('config.keymaps')
require('config.autocmds')

219
lua/config/keymaps.lua Normal file
View File

@@ -0,0 +1,219 @@
-- Custom keymaps
require("utils.functions")
local conf = require("conf")
-------------------------------------------------------
--------------------- KEYMAPS -------------------------
-------------------------------------------------------
-- Fast window switch
vim.keymap.set("n", "<leader>w", "<C-w>w")
vim.keymap.set('n', '<leader>zq', ':e ~/synced/brainstore/zettelkasten/input.txt<CR>`.zz')
vim.keymap.set("n", "<leader>me", ":mes<CR>")
vim.keymap.set("n", "<leader>snt", "<cmd>set nu<CR>")
vim.keymap.set("n", "<leader>snf", "<cmd>set nonu<CR>")
vim.keymap.set("n", "n", "nzz", { silent = true })
vim.keymap.set("n", "N", "Nzz", { silent = true })
vim.keymap.set("n", "<C-o>", "<C-o>zz", { silent = true })
vim.keymap.set("n", "<`C-i>", "<C-i>zz", { silent = true })
vim.keymap.set("n", "<C-u>", "<C-u>zz", { silent = true })
vim.keymap.set("n", "<C-d>", "<C-d>zz", { silent = true })
vim.keymap.set('n', '<leader>a', 'm9ggVG"+y`9')
vim.keymap.set('n', '<leader>va', 'ggVG')
vim.keymap.set('n', '<leader>tr', ':tabnew<CR>:term<CR>i')
-- Indent all will be replaced by the formatting of lsp where the lsp is installed
vim.keymap.set('n', '<leader>ia', 'gg=G<C-o>zz') -- This can break
vim.keymap.set('n', '<leader>ya', 'ggVG"+y<C-o>')
vim.keymap.set('n', '<leader>ss', ':wa<CR>')
vim.keymap.set("n", "<leader>nn", ":e ~/Nextcloud/Notes/quick.txt<CR>", { silent = true })
-- Folding
local opts = { noremap = true, silent = true }
local is_all_folded = false
local function toggle_fold()
if is_all_folded then
vim.opt.foldlevel = 99
else
vim.opt.foldlevel = 0
end
is_all_folded = not is_all_folded
end
vim.api.nvim_set_keymap("n", "<leader>ft", "za", opts) -- toggle fold under cursor
vim.keymap.set("n", "<leader>fs", toggle_fold, opts) -- close all folds
-- Quickly open some buffers
vim.keymap.set('n', '<leader>occ', ':e ~/.config/nvim/init.lua<CR>`.zz')
vim.keymap.set('n', '<leader>oct', ':e ~/synced/vault/contacts/contacts.txt<CR>`.zz')
vim.keymap.set('n', '<leader>ock', ':e ~/.config/nvim/lua/config/keymaps.lua<CR>`.zz')
vim.keymap.set('n', '<leader>ocd', ':e ~/.config/nvim/lua/config/autocmds.lua<CR>`.zz')
vim.keymap.set('n', '<leader>oco', ':e ~/.config/nvim/lua/config/options.lua<CR>`.zz')
vim.keymap.set('n', '<leader>ocl', ':e ~/.config/nvim/lua/config/lazy.lua<CR>`.zz')
vim.keymap.set('n', '<leader>oczl', ':e ~/.config/nvim/lua/config/lsp.lua<CR>`.zz')
vim.keymap.set('n', '<leader>ocp', ':e ~/.config/nvim/lua/plugins/misc.lua<CR>`.zz')
vim.keymap.set('n', '<leader>ocf', ':e ~/.config/nvim/lua/utils/functions.lua<CR>`.zz')
vim.keymap.set('n', '<leader>oca', ':e ~/.config/nvim/lua/utils/after.lua<CR>`.zz')
vim.keymap.set('n', '<leader>oq', ':e ~/synced/brainstore/input.txt<CR>`.zz')
vim.keymap.set('n', '<leader>ot', ':e ~/synced/brainstore/todos/todo.txt<CR>`.zz')
vim.keymap.set('n', '<leader>od', ':e ~/synced/brainstore/todos/done.txt<CR>`.zz')
vim.keymap.set('n', '<leader>ou', ':e ~/projects/university/' .. conf.season .. '/input.txt<CR>`.zz')
vim.keymap.set('n', '<leader>fd', ':e ~/projects/university/' .. conf.season .. '/input.txt<CR>`.zz')
vim.keymap.set('n', '<leader>oz', ':e ~/.zshrc<CR>`.zz')
vim.keymap.set('n', '<leader>oaa', ':e ~/.common_shell<CR>`.zz')
vim.keymap.set('n', '<leader>ow', ':e ~/synced/brainstore/waste.txt<CR>')
vim.keymap.set('n', '<leader>ohh', ':e ~/nixos/user/home.nix<CR>`.zz')
vim.keymap.set('n', '<leader>op', ':e ~/nixos/user/packages.nix<CR>`.zz')
vim.keymap.set('n', '<leader>on', ':e ~/nixos/configuration.nix<CR>`.zz')
vim.keymap.set('n', '<leader>om', ':e ~/nixos/modules/<CR>')
vim.keymap.set('n', '<leader>oho', ':e ~/nixos/hosts<CR>')
vim.keymap.set('n', '<leader>ll', ':Lazy<CR>')
vim.keymap.set('n', '<leader>sw', function()
local word = vim.fn.expand("<cword>")
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)" })
-- Substitution in visual mode
vim.keymap.set('v', '<leader>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', '<leader>pp', function()
vim.api.nvim_command('normal! "+p')
end, { desc = 'Paste from system clipboard' })
vim.keymap.set('v', '<leader>p', function()
vim.cmd('normal! "+p')
end, { desc = 'Yank to clipboard and keep the selection' })
vim.keymap.set('n', 'nh', ":noh<CR>")
vim.keymap.set('v', '<leader>y', function()
vim.cmd('normal! "+y')
vim.cmd('normal! gv')
end, { desc = 'Yank to clipboard and keep the selection' })
vim.keymap.set('i', '<C-k>', 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('<Right>', 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', '<C-j>', 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('<Left>', true, false, true), 'n', true)
else
if line > 1 then
vim.cmd('normal! k$')
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('<Right>', true, false, true), 'n', true)
end
end
end, { noremap = true, silent = true })
vim.keymap.set("n", "<leader>or",
function()
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
, { noremap = true, silent = true })
-- Fast quitter
vim.keymap.set('n', '<leader>q', function()
pcall(function()
vim.cmd('wa')
end)
vim.cmd('qa!')
end)
-- This needs to be refined for quick access to a new file or a recently edited one
vim.keymap.set('n', '<leader>ov',
function()
require('telescope.builtin').find_files({
prompt_title = "Select lecture in " .. conf.season,
cwd = conf.uni_dir,
find_command = {
"eza", "-1", "-D"
}
})
end
)
vim.keymap.set("n", "<leader>r",
function()
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
)
vim.keymap.set('n', '<leader>ok', function()
local current_date = os.date("%Y-%m-%d")
local week_number = os.date("%V")
local day_of_week = os.date("%a")
local path = "~/storage/notes/calendar/calendar_" .. os.date("%Y") .. ".txt"
local keys = ":e " ..
path .. "<CR>/" .. current_date .. " w" .. tonumber(week_number) .. " " .. day_of_week .. "<CR>$"
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), 'n', true)
end)

View File

@@ -34,3 +34,5 @@ require("lazy").setup({
enabled = false,
},
})
require("utils.after")

39
lua/config/options.lua Normal file
View File

@@ -0,0 +1,39 @@
vim.o.shiftwidth = 4;
vim.o.tabstop = 4;
vim.o.number = true;
vim.opt.relativenumber = true
vim.o.ignorecase = true;
--vim.o.guicursor = "n-v-c-sm-i-ci-ve:block";
vim.o.cursorline = true
vim.cmd([[
highlight CursorLine cterm=NONE guibg=#4c3c3c
]])
-- Disable mouse completly
vim.o.mouse = "";
-- Turn on undofile
vim.o.udf = true;
vim.opt.undolevels = 10000 -- Default is 1000
vim.opt.undoreload = 10000
-- Enable more colors
vim.opt.termguicolors = true
--vim.g.loaded_netrw = 1
--vim.g.loaded_netrwPlugin = 1
--vim.opt.signcolumn = "number"
vim.opt.signcolumn = "yes:1"
-- Enable Treesitter-based folding
vim.opt.foldmethod = "expr"
vim.opt.foldexpr = "nvim_treesitter#foldexpr()"
vim.opt.foldlevelstart = 99 -- open all folds by default
vim.opt.fillchars = "fold:╌"
vim.g.GPGDefaultRecipients = {"C6772451703DE183A4983CBA063DC054484835A6"}
vim.o.expandtab = true -- Use spaces instead of tabs
vim.o.smarttab = true -- Insert 'shiftwidth' spaces when pressing Tab

View File

@@ -0,0 +1,68 @@
local M = {}
local journal_base = vim.fn.expand("~/management/brainstore/knowledge/journal")
M.open_today = function()
local date = os.date("*t")
local day = os.date("%d")
local month = os.date("%m")
local year = tostring(date.year)
-- Define the filename and full path
local filename = string.format("%s.%s.md", day, month)
local full_path = string.format("%s/%s/%s", journal_base, year, filename)
-- Create the year folder if it doesn't exist
vim.fn.system({ "mkdir", "-p", journal_base .. "/" .. year })
-- Check if the file exists and create it if not
local file = io.open(full_path, "r")
if not file then
-- 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
-- Open the file for editing
vim.cmd("edit " .. full_path)
vim.cmd("normal! G")
end
M.search_this_month = function()
local date = os.date("*t")
local month = os.date("%m")
local year = tostring(date.year)
local path = string.format("%s/%s", journal_base, year)
-- Use telescope or fzf-lua
require('telescope.builtin').find_files {
prompt_title = "Journal Entries This Month",
cwd = path,
find_command = {
"rg", "--files", "--glob", "*.md", "-e", string.format("^\\d\\d.%s.md", month)
},
}
end
M.list_all_journals = function()
-- Use telescope or fzf-lua
require('telescope.builtin').find_files {
prompt_title = "All Journal Entries",
cwd = journal_base, -- Start from the base folder
find_command = {
"rg", "--files", "--glob", "*/??.??.md",
},
}
end
return M

239
lua/custom/linker/init.lua Normal file
View File

@@ -0,0 +1,239 @@
local M = {}
local brainstore_dir = "~/synced/brainstore"
local projects_dir = "~/projects"
local mail_dir = "~/mail/plain_emails"
local contacts_file = "~/synced/vault/contacts/contacts.txt"
local cal_dir = "~/synced/brainstore/calendar"
local function fzf_select(options, prompt, callback)
local fzf = require("fzf-lua")
fzf.fzf_exec(options, {
prompt = prompt .. "> ",
actions = {
["default"] = function(selected)
if selected and selected[1] then
callback(selected[1])
end
end,
},
})
end
local function spliting(inputstr, sep)
if sep == nil then
sep = "%s"
end
local t = {}
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
end
function M.insert_brainstore_link()
require('telescope.builtin').find_files({
hidden = true,
no_ignore = true,
follow = true,
prompt_title = "Things in Brain",
cwd = vim.fn.expand(brainstore_dir),
find_command = {
"rg", "--files",
"--hidden",
"--glob", "!**/.git/*",
"--glob", "!**/*.{jpg,png,gif,mp4,mkv,tar,zip,iso}",
},
attach_mappings = function(prompt_bufnr, map)
local actions = require('telescope.actions')
local action_state = require('telescope.actions.state')
local function insert_link()
local selection = action_state.get_selected_entry()
if not selection then
return
end
local selected = selection.path or selection.filename or selection[1]
if selected then
actions.close(prompt_bufnr)
local link = "[[brain:" .. selected:gsub(vim.fn.expand(brainstore_dir) .. "/", "") .. "]]"
vim.cmd("normal! h")
vim.api.nvim_put({ link }, "c", true, true)
end
end
map('i', '<CR>', insert_link)
map('n', '<CR>', insert_link)
return true
end
})
end
function M.insert_mail_link()
vim.fn.system("python " .. vim.fn.expand("~/projects/scripts/extract_mail.py"))
vim.fn.system("find " .. mail_dir .. " -type f > /tmp/mail_files")
local mails = vim.fn.readfile("/tmp/mail_files")
fzf_select(mails, "Mails", function(selected)
local link = "[[mail:" .. selected:gsub(vim.fn.expand(mail_dir) .. "/", "") .. "]]"
vim.api.nvim_put({ link }, "c", true, true)
end)
end
function M.insert_contact_link()
local contacts = vim.fn.readfile(vim.fn.expand(contacts_file))
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)
end)
end
function M.insert_date_link()
local year = os.date("%y")
local text = string.format("[[date:.%s]]", year)
vim.api.nvim_put({ text }, "c", true, true)
local row, col = table.unpack(vim.api.nvim_win_get_cursor(0))
vim.api.nvim_win_set_cursor(0, { row, col - 4 })
vim.cmd("startinsert")
end
function M.insert_project_link()
require('telescope.builtin').find_files({
hidden = true,
no_ignore = true,
disable_devicons = true,
follow = true,
prompt_title = "List of projects",
cwd = vim.fn.expand(projects_dir),
find_command = {
"eza", "-1", "-D",
},
attach_mappings = function(prompt_bufnr, map)
local actions = require('telescope.actions')
local action_state = require('telescope.actions.state')
local function insert_link()
local selection = action_state.get_selected_entry()
if not selection then
return
end
local selected = selection.path or selection.filename or selection[1]
if selected then
actions.close(prompt_bufnr)
local project = selected:gsub(vim.fn.expand(projects_dir) .. "/", "")
require('telescope.builtin').find_files({
hidden = true,
no_ignore = true,
follow = true,
disable_devicons = true,
prompt_title = "Pick a file. Press <ESC> to link just " .. project .. ".",
cwd = vim.fn.expand(selected),
find_command = {
"rg", "--files",
"--hidden",
"--glob", "!**/.git/*",
},
attach_mappings = function(prompt_bufnr_new, map_new)
actions = require('telescope.actions')
action_state = require('telescope.actions.state')
local function insert_link_new()
selection = action_state.get_selected_entry()
if not selection then
return
end
selected = selection.path or selection.filename or selection[1]
if selected then
actions.close(prompt_bufnr_new)
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_new)
local link = "[[project:" .. project .. "]]"
vim.api.nvim_put({ link }, "c", true, true)
end
map_new('i', '<CR>', insert_link_new)
map_new('n', '<CR>', insert_link_new)
map_new('i', '<ESC>', insert_link_top)
map_new('n', '<ESC>', insert_link_top)
return true
end
})
end
end
map('i', '<CR>', insert_link)
map('n', '<CR>', insert_link)
return true
end
})
end
function M.follow_link()
local line = vim.api.nvim_get_current_line()
local link = line:match("%[%[(.-)%]%]")
if not link then
print("No link found on this line.")
return
end
local kind, target = link:match("^(.-):(.*)$")
if not kind or not target then
print("Invalid link format.")
return
end
-- List of all kinds that are available
if kind == "brain" then
vim.cmd("edit " .. brainstore_dir .. "/" .. target)
elseif kind == "mail" then
vim.cmd("edit " .. mail_dir .. "/" .. target)
elseif kind == "contact" then
vim.cmd("vsplit " .. contacts_file)
vim.cmd("/" .. target)
elseif kind == "project" then
vim.cmd("edit " .. projects_dir .. "/" .. target)
elseif kind == "date" then
-- target: "4.3.25" or "03.04.2034"
local splits = spliting(target, '.')
local day = pad2(splits[1])
local month = pad2(splits[2])
local year = splits[3]
if #year == 4 then
year = year:sub(3, 4)
end
vim.cmd("edit " .. cal_dir .. "/calendar_20" .. year .. ".txt")
vim.cmd("/" .. "20" .. year .. "-" .. month .. "-" .. day)
vim.cmd("normal! zz")
else
print("Unknown link type: " .. kind .. ".")
end
end
return M

103
lua/custom/todo/init.lua Normal file
View File

@@ -0,0 +1,103 @@
local M = {}
local function is_todo_file()
return vim.fn.expand("%:t") == "todo.txt"
end
function M.set_priority(letter)
if not is_todo_file() then return end
local line = vim.api.nvim_get_current_line()
line = line:gsub("^%(%u%)%s*", "")
vim.api.nvim_set_current_line(string.format("(%s) %s", letter:upper(), line))
end
-- Remove priority
function M.remove_priority()
if not is_todo_file() then return end
local line = vim.api.nvim_get_current_line()
line = line:gsub("^%(%u%)%s*", "")
vim.api.nvim_set_current_line(line)
end
function M.mark_done()
if not is_todo_file() then return end
print("Marked todo as done! (just deleted)")
vim.cmd("normal! dd")
end
-- Util: remove empty lines
local function strip_blank_lines(lines)
local cleaned = {}
for _, line in ipairs(lines) do
if line:match("%S") then
table.insert(cleaned, line)
end
end
return cleaned
end
-- Grouped sort logic
local function grouped_sort(key_fn)
if not is_todo_file() then return end
local lines = strip_blank_lines(vim.api.nvim_buf_get_lines(0, 0, -1, false))
local buckets = {}
for _, line in ipairs(lines) do
local key = key_fn(line)
if not buckets[key] then
buckets[key] = {}
end
table.insert(buckets[key], line)
end
local sorted_keys = {}
for key in pairs(buckets) do table.insert(sorted_keys, key) end
table.sort(sorted_keys)
local final_lines = {}
for _, key in ipairs(sorted_keys) do
for _, line in ipairs(buckets[key]) do
table.insert(final_lines, line)
end
table.insert(final_lines, "") -- add blank line after group
end
-- Remove final blank line if it exists
if final_lines[#final_lines] == "" then
table.remove(final_lines)
end
vim.api.nvim_buf_set_lines(0, 0, -1, false, final_lines)
end
-- Key extractors
local function get_priority_key(line)
local p = line:match("^%((%u)%)")
return p and p or "~" -- tilde = sorts after all letters
end
local function get_context_key(line)
local c = line:match("@(%w+)")
return c and c or "~"
end
local function get_project_key(line)
local p = line:match("%+(%w+)")
return p and p or "~"
end
-- Sorters
function M.sort_by_priority()
grouped_sort(get_priority_key)
end
function M.sort_by_context()
grouped_sort(get_context_key)
end
function M.sort_by_project()
grouped_sort(get_project_key)
end
return M

102
lua/custom/typst/init.lua Normal file
View File

@@ -0,0 +1,102 @@
local M = {}
local functions = require("utils.functions")
local watch_job_id = nil
local watch_buf_id = nil
local watch_tab_id = nil
function M.watch_and_open()
-- Parse the current file and check for typst
vim.notify("INIT", vim.log.levels.WARN)
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
-- 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
local output = dir .. "/" .. filename
-- 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
local 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)
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)
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
function M.just_open()
-- Parse the current file and check for typst
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
local output = dir .. "/" .. filename
-- Start typst watch
local cwd = vim.fn.getcwd() -- set the starting directory
-- TODO: root setting does not work
local watch_cmd = { "typst", "compile", "--root", cwd, input, output }
vim.fn.jobstart(watch_cmd)
functions.sleep(0.5)
vim.fn.jobstart({ "sioyek", output })
end
return M

187
lua/custom/uni/init.lua Normal file
View File

@@ -0,0 +1,187 @@
local M = {}
local fzf = require("fzf-lua")
local fn = vim.fn
local conf = require("conf")
-- Function to scan for .unicourse files and get their course directories
function M.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
scan_dir("~/projects/university/" .. conf.season)
return dirs
end
-- Function to show the fzf menu for selecting a course directory
function M.select_course_directory()
local courses = M.get_course_directories()
local course_names = {}
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
M.show_course_menu(course)
break
end
end
end,
},
})
end
-- Function to show the fzf menu for actions on a selected course folder
function M.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
-- 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",
}
fzf.fzf_exec(options, {
prompt = "Choose an action > ",
actions = {
["default"] = function(selected)
if selected[1] == "Open the newest VL file" then
local newest_file = M.get_newest_vl_file(files)
vim.cmd("edit " .. newest_file)
elseif selected[1] == "Create a new VL" then
M.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 M.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
end
-- Function to insert chapter reference at top summary section
local function add_chapter_to_summary(course, new_vl_name)
local book_file = vim.fn.expand(conf.book_file)
local rel_path = string.format("%s/VL/%s", course.path:match("university/(.+)$"), new_vl_name)
local default_title = new_vl_name
local chapter_line = string.format(' - #chapter("%s")[%s]\n', rel_path, default_title:match("^(.-)%."))
local lines = {}
for l in io.lines(book_file) do
table.insert(lines, l)
end
local out = io.open(book_file, "w")
local inserted = false
local right_block = false
for _, l in ipairs(lines) do
-- insert after the course's existing index line
if not inserted and l:match('"' .. course.path:match("university/(.+)$") .. '/index.typ"') then
right_block = true
end
if not inserted and right_block and l:match("^%s*$") then
out:write(chapter_line .. "\n" .. l)
inserted = true
else
out:write(l .. "\n")
end
end
out:close()
end
-- Function to create a new VL file based on the template and incrementing the number
function M.create_new_vl(course)
local vl_dir = course.path .. "/VL"
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
--- @type number?
local latest_num = 0
for _, file in ipairs(fn.glob(vl_dir .. "/*", true, true)) do
if file:match(course.short .. "VL(%d+).typ$") then
--- @type number?
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
-- Copy the template if it exists
vim.fn.system({ "cp", template_path, new_vl_path })
add_chapter_to_summary(course, new_vl_name)
-- Open the new VL file
vim.cmd("edit " .. new_vl_path)
else
print("Template file (template.typ) not found!")
end
end
return M

View File

@@ -0,0 +1,21 @@
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
require("gruvbox").setup({
palette_overrides = {
bright_yellow = "#AD5944"; -- workaround
}
})
vim.cmd.colorscheme("gruvbox")
transparentBackground()
end
}

72
lua/plugins/custom.lua Normal file
View File

@@ -0,0 +1,72 @@
--- @param name? string
--- @return string
local function get_custom_dir(name)
if name == nil then
return vim.fn.stdpath("config") .. "/lua/custom"
end
return vim.fn.stdpath("config") .. "/lua/custom/" .. name
end
return {
{
dir = get_custom_dir("todo"),
name = "todo",
dependencies = { "nvim-lua/plenary.nvim", "nvim-telescope/telescope.nvim" },
keys = {
{ "<leader>ta", function() require("custom.todo").mark_done() end, desc = "Watch Typst" },
},
},
{
dir = get_custom_dir("typst"),
name = "typst",
dependencies = { "nvim-lua/plenary.nvim", "nvim-telescope/telescope.nvim" },
keys = {
{ "<leader>tw", function() require("custom.typst").watch_and_open() end, desc = "Watch Typst" },
},
},
{
dir = get_custom_dir("typst"),
name = "typst",
dependencies = { "nvim-lua/plenary.nvim", "nvim-telescope/telescope.nvim" },
keys = {
{ "<leader>tu", function() require("custom.typst").just_open() end, desc = "Open Typst" },
},
},
{
dir = get_custom_dir("journal"),
name = "journal",
config = function ()
local journal = require("custom.journal")
vim.keymap.set("n", "<leader>joup", function()
journal.open_today()
end, { desc = "Open todays journal" })
end
},
{
dir = get_custom_dir("uni"),
name = "uni",
config = function ()
local uni = require("custom.uni")
vim.keymap.set("n", "<leader>nv", function()
uni.select_course_directory()
end, { desc = "Open UniCourse menu" })
end
},
{
dir = get_custom_dir("linker"),
name = "linker",
config = function()
local links = require("custom.linker")
vim.keymap.set("n", "<leader>fl", links.follow_link, { desc = "Try to follow current link" })
vim.keymap.set("n", "<leader>lf", links.insert_brainstore_link, { desc = "Link Brainstore file" })
vim.keymap.set("n", "<leader>lm", links.insert_mail_link, { desc = "Link Mail" })
vim.keymap.set("n", "<leader>lp", links.insert_project_link, { desc = "Link Project" })
vim.keymap.set("n", "<leader>lc", links.insert_contact_link, { desc = "Link Contact" })
vim.keymap.set("n", "<leader>ld", links.insert_date_link, { desc = "Link Contact" })
end
},
}

92
lua/plugins/git.lua Normal file
View File

@@ -0,0 +1,92 @@
return {
{
"kdheepak/lazygit.nvim",
lazy = true,
cmd = {
"LazyGit",
"LazyGitConfig",
"LazyGitCurrentFile",
"LazyGitFilter",
"LazyGitFilterCurrentFile",
},
dependencies = {
"nvim-lua/plenary.nvim", -- Floating boarders
},
keys = {
{ "<leader>lg", "<cmd>LazyGit<cr>", 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', '<leader>hs', gitsigns.stage_hunk)
map('n', '<leader>hr', gitsigns.reset_hunk)
map('v', '<leader>hs', function()
gitsigns.stage_hunk({ vim.fn.line('.'), vim.fn.line('v') })
end)
map('v', '<leader>hr', function()
gitsigns.reset_hunk({ vim.fn.line('.'), vim.fn.line('v') })
end)
map('n', '<leader>hS', gitsigns.stage_buffer)
map('n', '<leader>hR', gitsigns.reset_buffer)
map('n', '<leader>hp', gitsigns.preview_hunk)
map('n', '<leader>hi', gitsigns.preview_hunk_inline)
map('n', '<leader>hb', function()
gitsigns.blame_line({ full = true })
end)
map('n', '<leader>hd', gitsigns.diffthis)
map('n', '<leader>hD', function()
gitsigns.diffthis('~')
end)
map('n', '<leader>hQ', function() gitsigns.setqflist('all') end)
map('n', '<leader>hq', gitsigns.setqflist)
-- Toggles
map('n', '<leader>tb', gitsigns.toggle_current_line_blame)
-- map('n', '<leader>tw', gitsigns.toggle_word_diff)
-- Text object
map({ 'o', 'x' }, 'ih', gitsigns.select_hunk)
end
gitsigns.setup({ on_attach = on_attach })
end
}
}

212
lua/plugins/lsp.lua Normal file
View File

@@ -0,0 +1,212 @@
-- Prefilled with servers that have no dependencies
local servers = require("utils.functions").get_lsp_servers()
return {
{
"stevearc/aerial.nvim",
dependencies = {
"nvim-treesitter/nvim-treesitter",
"nvim-tree/nvim-web-devicons"
},
config = true,
keys = {
{
"<leader>ae",
function()
require("aerial")
vim.cmd("AerialToggle")
end
},
{
"}",
function()
require("aerial")
vim.cmd("AerialNext")
end
},
{
"{",
function()
require("aerial")
vim.cmd("AerialPrev")
end
},
},
},
{
"nvimdev/lspsaga.nvim",
opts = {
lightbulb = {
enable = false,
enable_in_insert = false,
sign = false,
virtual_text = false,
},
},
},
{
"williamboman/mason.nvim",
dependencies = {
"williamboman/mason-lspconfig.nvim"
},
priority = -10,
config = function()
require("mason").setup()
-- Workaround for local lsp only
-- does not work so nice on non nixos systems
local servers_modified = servers
for i, v in ipairs(servers_modified) do
if v == "zls" then
table.remove(servers_modified, i)
break
end
if v == "clangd" then
table.remove(servers_modified, i)
break
end
if v == "hls" then
table.remove(servers_modified, i)
break
end
end
require("mason-lspconfig").setup({
ensure_installed = servers_modified,
automatic_enable = false,
})
end,
},
{
"folke/lazydev.nvim",
ft = "lua", -- only load on lua files
opts = {
library = {
-- See the configuration section for more details
-- Load luvit types when the `vim.uv` word is found
{ path = "${3rd}/luv/library", words = { "vim%.uv" } },
{
path = "${3rd}/love2d/library", },
},
},
},
{
"hrsh7th/nvim-cmp",
dependencies = {
"hrsh7th/cmp-path",
"saadparwaiz1/cmp_luasnip",
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
},
config = function()
local cmp = require("cmp")
local border = "single"
local max_entries = 7
cmp.setup({
window = {
completion = cmp.config.window.bordered({
border = border,
scrollbar = false,
}),
documentation = cmp.config.window.bordered({
border = border,
scrollbar = false,
}),
},
snippet = {
expand = function(args) require("luasnip").lsp_expand(args.body) end,
},
mapping = cmp.mapping.preset.insert({
["<C-Space>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
["<Tab>"] = cmp.mapping.select_next_item(),
["<S-Tab>"] = cmp.mapping.select_prev_item(),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" },
}, {
{ name = "buffer" },
{ name = "path" },
}),
performance = {
debounce = 60,
throttle = 30,
fetching_timeout = 500,
filtering_context_budget = 3,
confirm_resolve_timeout = 80,
async_budget = 1,
max_view_entries = max_entries,
}
})
end
},
{
"neovim/nvim-lspconfig",
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"L3MON4D3/LuaSnip",
},
config = function()
-- Custom overwrites for servers
local server_settings = {}
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", "<C-k>", vim.lsp.buf.signature_help, opts)
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
vim.keymap.set("n", "]d", function()
vim.diagnostic.jump({ count = 1, float = true })
end, opts)
vim.keymap.set("n", "[d", function()
vim.diagnostic.jump({ count = -1, float = true })
end, opts)
vim.keymap.set("n", "<leader>lwa", vim.lsp.buf.add_workspace_folder, opts)
vim.keymap.set("n", "<leader>lwr", vim.lsp.buf.remove_workspace_folder, opts)
vim.keymap.set("n", "<leader>lwl", function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, opts)
vim.keymap.set("n", "<leader>ff", function()
vim.lsp.buf.format({ async = true })
end, opts)
end
-- Setup and enable 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
vim.lsp.config(server, config)
vim.lsp.enable(server)
end
-- Add text in diagnostics
vim.diagnostic.config({
virtual_text = false,
})
end,
},
}

25
lua/plugins/luasnip.lua Normal file
View File

@@ -0,0 +1,25 @@
return {
{
"L3MON4D3/LuaSnip",
dependencies = {
"rafamadriz/friendly-snippets"
},
version = "v2.*",
build = "make install_jsregexp",
event = "InsertEnter",
config = function()
local ls = require("luasnip")
-- Load snippets
require("luasnip.loaders.from_vscode").lazy_load()
require("luasnip.loaders.from_lua").lazy_load({ paths = "~/.config/nvim/snippets" })
ls.config.setup({
enable_autosnippets = true,
store_selection_keys = '<Tab>',
})
vim.keymap.set({ "i", "s" }, "<C-L>", function() ls.jump(1) end, { silent = true })
vim.keymap.set({ "i", "s" }, "<C-H>", function() ls.jump(-1) end, { silent = true })
end,
},
}

86
lua/plugins/misc.lua Normal file
View File

@@ -0,0 +1,86 @@
return {
{
"ThePrimeagen/harpoon",
config = function()
vim.keymap.set("n", "<leader>af", function()
require("harpoon.mark").add_file()
end)
vim.keymap.set("n", "<leader>hf", function()
require("harpoon.ui").toggle_quick_menu()
end)
vim.keymap.set("n", "<leader>Hn", function()
require("harpoon.ui").nav_next()
end)
vim.keymap.set("n", "<leader>Hp", function()
require("harpoon.ui").nav_prev()
end)
end
},
--{
-- 'Exafunction/windsurf.vim',
-- event = 'BufEnter'
--},
{
"Ascyii/vim-gnupg",
dev = true
},
{
"akinsho/toggleterm.nvim",
config = function()
-- Cannot setup with opts here need to call before using the command for the plugin
require("toggleterm").setup({
size = 20,
direction = "horizontal",
})
local first_open = false
local function toggle_term()
vim.cmd("ToggleTerm")
if first_open == true then
vim.cmd("startinsert")
end
end
vim.keymap.set("n", "<C-/>", toggle_term, { noremap = true, silent = true })
vim.keymap.set("t", "<C-/>", toggle_term, { noremap = true, silent = true })
end
},
{
'Ascyii/telekasten.nvim',
dev = true,
config = function()
local base_zet = "~/Nextcloud/Notes"
-- Again can only use opts when not using config
require("telekasten").setup({
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 = "-",
})
-- Telekasten occupies the z namespace
vim.keymap.set("n", "<leader>z", "<cmd>Telekasten panel<CR>")
vim.keymap.set("n", "<leader>zf", "<cmd>Telekasten find_notes<CR>")
vim.keymap.set("n", "<leader>zg", "<cmd>Telekasten search_notes<CR>")
vim.keymap.set("n", "<leader>zd", "<cmd>Telekasten goto_today<CR>")
vim.keymap.set("n", "<leader>zr", "<cmd>Telekasten rename_note<CR>")
vim.keymap.set("n", "<leader>zz", "<cmd>Telekasten follow_link<CR>")
vim.keymap.set("n", "<leader>zn", "<cmd>Telekasten new_note<CR>")
vim.keymap.set("n", "<leader>zb", "<cmd>Telekasten show_backlinks<CR>")
vim.keymap.set("n", "<leader>zw", "<cmd>Telekasten find_weekly_notes<CR>")
vim.keymap.set("n", "<leader>il", "<cmd>Telekasten insert_link<CR>")
vim.keymap.set("n", "<leader>zI", "<cmd>Telekasten insert_img_link<CR>")
end
},
};

62
lua/plugins/nvimtree.lua Normal file
View File

@@ -0,0 +1,62 @@
return {
"nvim-tree/nvim-tree.lua",
cmd = {"NvimTreeOpen"},
keys = {
{ "<leader>e", function()
require("nvim-tree.api").tree.toggle({
find_file = true,
update_root = true,
focus = true,
})
end
}
},
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 = true,
folder = true,
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,
},
},
}
}

86
lua/plugins/searching.lua Normal file
View File

@@ -0,0 +1,86 @@
return {
{
"ibhagwan/fzf-lua",
dependencies = { "nvim-tree/nvim-web-devicons" },
cmd = { "FzfLua" },
},
{
"nvim-telescope/telescope.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
lazy = true,
keys = {
{
"<leader>tt",
":Telescope<CR>",
desc = "Telescope menu",
},
{
"<C-p>",
function()
require("telescope.builtin").buffers()
end,
desc = "Fzf current buffers"
},
{
"<leader>fr",
function()
require('telescope.builtin').oldfiles({
disable_devicons = true,
})
end,
desc = "Open last files"
},
{
"<leader>g",
function()
require('utils.functions').fzf_wrapped("grep")
end
},
{
"<leader>fh",
function()
require('telescope.builtin').help_tags()
end,
},
{
"<leader><leader>",
function()
require('utils.functions').fzf_wrapped("find")
end
}
},
config = true,
},
{
"debugloop/telescope-undo.nvim",
dependencies = {
{
"nvim-telescope/telescope.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
},
},
keys = {
{
"<leader>u",
"<cmd>Telescope undo<cr>",
desc = "undo history",
},
},
opts = {
extensions = {
undo = {
side_by_side = true,
layout_strategy = "vertical",
layout_config = {
preview_height = 0.7,
},
},
},
},
config = function(_, opts)
require("telescope").setup(opts)
require("telescope").load_extension("undo")
end,
}
}

View File

@@ -1,4 +0,0 @@
return {
'nvim-telescope/telescope.nvim',
dependencies = { 'nvim-lua/plenary.nvim' }
}

View File

@@ -0,0 +1,21 @@
return {
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
priority = 1000,
config = function()
local configs = require("nvim-treesitter.configs")
configs.setup({
sync_install = true,
ensure_installed = { "css", "html", "rust", "php", "typst", "go", "bash", "python", "nix", "lua", "cpp", "c", "java" },
auto_install = true,
highlight = { enable = true },
indent = { enable = true },
fold = { enable = true },
ignore_install = {},
modules = {},
})
end
},
}

50
lua/plugins/typstar.lua Normal file
View File

@@ -0,0 +1,50 @@
return {
{
"Ascyii/typstar",
dependencies = {
"L3MON4D3/LuaSnip",
"nvim-treesitter/nvim-treesitter",
},
dev = true,
ft = { "typst" },
keys = {
{
"<M-t>",
"<Cmd>TypstarToggleSnippets<CR>",
mode = { "n", "i" },
},
{
"<M-j>",
"<Cmd>TypstarSmartJump<CR>",
mode = { "s", "i" },
},
{
"<M-k>",
"<Cmd>TypstarSmartJumpBack<CR>",
mode = { "s", "i" },
},
{
"<leader>ti",
":TypstarInsertRnote<CR>",
},
{
"<leader>td",
":TypstarDeleteRnote<CR>",
},
{
"<leader>to",
":TypstarOpenDrawing<CR>",
},
},
config = function()
local typstar = require("typstar")
typstar.setup({
add_undo_breakpoints = true,
typstarRoot = "~/projects/typstar",
rnote = {
assetsDir = 'typst-assets',
},
})
end,
},
}

63
lua/plugins/ui.lua Normal file
View File

@@ -0,0 +1,63 @@
local utils = require("utils.functions")
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 = true,
theme = 'gruvbox',
component_separators = { left = '', right = '' },
section_separators = { left = '', right = '' },
always_divide_middle = true,
always_show_tabline = false,
globalstatus = false,
refresh = {
statusline = 300,
tabline = 300,
winbar = 300,
}
},
sections = {
lualine_a = { 'mode' },
lualine_b = { 'branch', 'diff', 'diagnostics' },
lualine_c = { utils.get_cwd(), 'filename' },
lualine_x = { 'encoding', 'fileformat', 'filetype' },
lualine_y = { 'progress' },
lualine_z = { 'location' }
},
extensions = { "nvim-tree" } -- show another line on the tree
}
},
{
'romgrk/barbar.nvim',
dependencies = {
'lewis6991/gitsigns.nvim',
'nvim-tree/nvim-web-devicons',
},
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
config = function()
vim.keymap.set("n", "L", ":BufferNext<CR>", { silent = true })
vim.keymap.set("n", "H", ":BufferPrevious<CR>", { silent = true })
vim.keymap.set("n", "<leader>bd", ":BufferDelete<CR>")
end
},
}

View File

@@ -1,3 +0,0 @@
return {
'mbbill/undotree'
}

21
lua/utils/after.lua Normal file
View File

@@ -0,0 +1,21 @@
local function rounded_border()
return { '', '', '', '', '', '', '', '' }
end
-- Buffer the original fuction
local nvim_open_win = vim.api.nvim_open_win
-- Set color to a slight gray
vim.api.nvim_set_hl(0, 'FloatBorder', { bg = 'None', fg = '#a0a0a0' })
vim.api.nvim_set_hl(0, 'NormalFloat', { bg = 'None' })
-- Border overwrite
vim.api.nvim_open_win = function(buf, enter, opts)
opts = opts or {}
if opts.border == nil then
opts.border = rounded_border()
end
return nvim_open_win(buf, enter, opts)
end

138
lua/utils/functions.lua Normal file
View File

@@ -0,0 +1,138 @@
-- General helper functions
local M = {}
function M.sleep(n)
os.execute("sleep " .. tonumber(n))
end
--- @return string
function M.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
function M.fzf_wrapped(type)
local t = require("telescope.builtin")
if type == "grep" then
t.live_grep({
disable_devicons = true,
cwd = vim.fn.getcwd(),
additional_args = function()
return { '--hidden', '--glob', '!.git/*' }
end,
})
end
if type == "find" then
t.find_files({
hidden = true,
no_ignore = true,
follow = true,
disable_devicons = false,
prompt_title = "Find Files",
find_command = {
"rg", "--files",
"--glob", "!**/.git/*",
"--glob", "!**/build/*",
"--glob", "!**/*.{jpg,png,gif,mp4,mkv,tar,zip,iso}"
}
})
end
end
--- @return {}
function M.get_lsp_servers()
local servers = { "lua_ls" }
-- persistent state file
local state_file = vim.fn.stdpath("state") .. "/mason_skipped_jonas.json"
-- load previous warnings
local warned = {}
local ok, data = pcall(vim.fn.readfile, state_file)
if ok and #data > 0 then
local decoded = vim.fn.json_decode(data)
if decoded then warned = decoded end
end
local function save_state()
vim.fn.writefile({ vim.fn.json_encode(warned) }, state_file)
end
local function warn_once(key, msg)
if not warned[key] then
vim.notify(msg, vim.log.levels.WARN)
warned[key] = true
save_state()
end
end
local function populate_servers()
if vim.fn.executable("go") == 1 then
table.insert(servers, "gopls")
else
warn_once("gopls", "[mason] Skipping gopls (go not found)")
end
if vim.fn.executable("php") == 1 then
table.insert(servers, "intelephense")
else
warn_once("php", "[mason] Skipping intelephense (php not found)")
end
if vim.fn.executable("hls") == 1 then
table.insert(servers, "hls")
else
warn_once("haskell", "[mason] Skipping hls (hls not found)")
end
if vim.fn.executable("npm") == 1 then
if vim.fn.executable("clangd") == 1 then
table.insert(servers, "clangd")
end
if vim.fn.executable("java") == 1 then
table.insert(servers, "jdtls")
end
table.insert(servers, "pyright")
table.insert(servers, "bashls")
table.insert(servers, "cssls")
table.insert(servers, "html")
table.insert(servers, "jsonls")
else
warn_once("npm", "[mason] Skipping npm related (npm not found)")
end
if vim.fn.executable("cargo") == 1 then
if vim.fn.executable("nix") == 1 then
table.insert(servers, "nil_ls")
else
warn_once("nix", "[mason] Skipping nil_ls and nixfmt (nix not found)")
end
table.insert(servers, "rust_analyzer")
else
warn_once("cargo", "[mason] Skipping nil_ls/rust_analyzer (cargo not found)")
end
if vim.fn.executable("deno") == 1 then
table.insert(servers, "ts_ls")
else
warn_once("deno", "[mason] Skipping denols and tsserver (deno not found)")
end
if vim.fn.executable("zls") == 1 then
table.insert(servers, "zls")
end
end
populate_servers()
return servers
end
return M

9
snippets/all.lua Normal file
View File

@@ -0,0 +1,9 @@
local ls = require("luasnip")
local s = ls.snippet
local t = ls.text_node
return {
s("sig", {
t("Best regards,"), t({ "", "Jonas Hahn" }),
}),
}