diff --git a/.config/i3/config b/.config/i3/config new file mode 100644 index 0000000..eec0f73 --- /dev/null +++ b/.config/i3/config @@ -0,0 +1,21 @@ +# define modifier keys +set $mod mod4 +set $alt mod1 + +# define workspaces +set $ws1 "1" +set $ws2 "2" +set $ws3 "3" +set $ws4 "4" +set $ws5 "5" +set $ws6 "6" +set $ws7 "7" +set $ws8 "8" +set $ws9 "9" +set $ws10 "10" +set $ws11 "11" +set $ws12 "12" + +# include different modules (may not include definitions shared across multiple units) +include $XDG_CONFIG_HOME/i3/config.d/*.conf +exec --no-startup-id i3-msg 'workspace $ws1' diff --git a/.config/i3/config.d/applications.conf b/.config/i3/config.d/applications.conf new file mode 100644 index 0000000..a4939c0 --- /dev/null +++ b/.config/i3/config.d/applications.conf @@ -0,0 +1,28 @@ +# assign custom classes to specific workspaces +# to more easily assign apps to specific workspaces temporarily +assign [class="app-ws1"] $ws1 +assign [class="app-ws2"] $ws2 +assign [class="app-ws3"] $ws3 +assign [class="app-ws4"] $ws4 +assign [class="app-ws5"] $ws5 +assign [class="app-ws6"] $ws6 +assign [class="app-ws7"] $ws7 +assign [class="app-ws8"] $ws8 +assign [class="app-ws9"] $ws9 +assign [class="app-ws10"] $ws10 +assign [class="app-ws11"] $ws11 +assign [class="app-ws12"] $ws12 + +# assign applications to specific workspaces +# TODO: I'd prefer to switch to the designated workspace when it's launched in another workspace. +# assign [class="Spotify"] $ws8 +assign [class="vesktop"] $ws9 + +# autostart applications on a specific workspace +exec --no-startup-id i3-msg 'workspace $ws2; exec firefox --new-window' +exec --no-startup-id i3-msg 'workspace $ws1; exec kitty --single-instance' + +# autostart applications in general (usually always assigned to a workspace) +exec --no-startup-id flatpak run dev.vencord.Vesktop +# exec --no-startup-id spotify +exec --no-startup-id blueman-applet diff --git a/.config/i3/config.d/display.conf b/.config/i3/config.d/display.conf new file mode 100644 index 0000000..bc0b7f4 --- /dev/null +++ b/.config/i3/config.d/display.conf @@ -0,0 +1,36 @@ +# set the font +font pango:JetBrainsMonoNLNerdFont-Regular 10 + +# launch polybar +exec_always --no-startup-id $XDG_CONFIG_HOME/polybar/launch.sh + +# set the border width (and remove title bars) +default_orientation vertical +for_window [class=".*"] border pixel 1 +# for_window [floating] border pixel 5 +for_window [class=".*"] split toggle + +set $scr1 "eDP-1" +set $scr2 "HDMI-1" + +# set xrandr settings +exec_always xrandr --auto \ + --output $scr1 --dpi 96 --primary \ + --output $scr2 --dpi 96 --above $scr1 + +# attach each workspace to a specific screen +workspace $ws1 output $scr1 +workspace $ws2 output $scr1 +workspace $ws3 output $scr1 +workspace $ws4 output $scr1 +workspace $ws5 output $scr1 +workspace $ws6 output $scr1 +workspace $ws7 output $scr1 +workspace $ws8 output $scr1 +workspace $ws9 output $scr1 +workspace $ws10 output $scr2 +workspace $ws11 output $scr2 +workspace $ws12 output $scr2 + +# update the satellite render +exec_always ~/usr/bin/satallite-wp-update diff --git a/.config/i3/config.d/keymap.conf b/.config/i3/config.d/keymap.conf new file mode 100644 index 0000000..86ac3b0 --- /dev/null +++ b/.config/i3/config.d/keymap.conf @@ -0,0 +1,79 @@ +# +# OS-shortcuts +# +# workspace navigation +bindsym $mod+ctrl+h workspace prev +# TODO: multi-monitor setup using J/K? +bindsym $mod+ctrl+l workspace next + +# window navigation +bindsym $mod+h focus left +bindsym $mod+j focus down +bindsym $mod+k focus up +bindsym $mod+l focus right + +# move windows +bindsym $mod+shift+h move left +bindsym $mod+shift+j move down +bindsym $mod+shift+k move up +bindsym $mod+shift+l move right + +# closing windows (kill uses WM_DELETE, if available) (split is toggled for quasi alternating layout) +bindsym $mod+q split toggle kill +bindsym $alt+F4 split toggle kill + +# toggle between the different possible splits +bindsym $mod+F10 fullscreen toggle +bindsym $mod+e layout toggle split + +# system commands +bindsym $mod+shift+c reload +bindsym $mod+shift+r restart +bindsym $mod+shift+e exit +bindsym $mod+shift+f floating toggle +bindsym $mod+o exec --no-startup-id xlock -mode petri -delay 20000 -size 2 -ncolors 16 -saturation 0.4 -echokeys -echokey '*' -usefirst + +# +# XF86 key actions +# +# volume control +bindsym XF86AudioRaiseVolume exec --no-startup-id x-volume up +bindsym XF86AudioLowerVolume exec --no-startup-id x-volume down +bindsym XF86AudioMute exec --no-startup-id x-volume mute +bindsym XF86AudioMicMute exec --no-startup-id x-mic-mute + +# brightness control +bindsym XF86MonBrightnessUp exec --no-startup-id x-brightness-up +bindsym XF86MonBrightnessDown exec --no-startup-id x-brightness-down + +# media controls +bindsym XF86AudioPlay exec playerctl play-pause +bindsym XF86AudioPause exec playerctl play-pause +bindsym XF86AudioNext exec playerctl next +bindsym XF86AudioPrev exec playerctl previous + +# app launchers and such +bindsym XF86Calculator exec --no-startup-id kitty -e 'calc' + +# +# apps +# +# pickers +bindsym $mod+F5 exec --no-startup-id rofi -show window +bindsym $mod+space exec --no-startup-id rofi -show drun +bindsym $mod+period exec --no-startup-id rofi -show emoji -config emoji + +# terminal +bindsym $mod+Return exec --no-startup-id kitty --single-instance +bindsym $mod+t exec --no-startup-id kitty --single-instance +bindsym $mod+backslash exec --no-startup-id kitty --single-instance + +# internet browser +bindsym $mod+b exec --no-startup-id firefox --new-window +bindsym $mod+shift+b exec --no-startup-id firefox --new-window --private-window + +# screenshot +bindsym $mod+shift+s exec --no-startup-id maim -f png -s | xclip -selection clipboard -t image/png +bindsym Print exec --no-startup-id maim -f png | xclip -selection clipboard -t image/png +bindsym $mod+ctrl+shift+s exec --no-startup-id maim -f png -s > $(xdg-user-dir PICTURES)/screenshot.png +bindsym $mod+Print+s exec --no-startup-id maim -f png > $(xdg-user-dir PICTURES)/screenshot.png diff --git a/.config/i3/config.d/workspace.conf b/.config/i3/config.d/workspace.conf new file mode 100644 index 0000000..a852e0e --- /dev/null +++ b/.config/i3/config.d/workspace.conf @@ -0,0 +1,27 @@ +# workspace switch keybinds +bindsym $mod+1 workspace $ws1 +bindsym $mod+2 workspace $ws2 +bindsym $mod+3 workspace $ws3 +bindsym $mod+4 workspace $ws4 +bindsym $mod+5 workspace $ws5 +bindsym $mod+6 workspace $ws6 +bindsym $mod+7 workspace $ws7 +bindsym $mod+8 workspace $ws8 +bindsym $mod+9 workspace $ws9 +bindsym $mod+0 workspace $ws10 +bindsym $mod+minus workspace $ws11 +bindsym $mod+equal workspace $ws12 + +# move containers to workspaces +bindsym $mod+shift+1 move container to workspace $ws1 +bindsym $mod+shift+2 move container to workspace $ws2 +bindsym $mod+shift+3 move container to workspace $ws3 +bindsym $mod+shift+4 move container to workspace $ws4 +bindsym $mod+shift+5 move container to workspace $ws5 +bindsym $mod+shift+6 move container to workspace $ws6 +bindsym $mod+shift+7 move container to workspace $ws7 +bindsym $mod+shift+8 move container to workspace $ws8 +bindsym $mod+shift+9 move container to workspace $ws9 +bindsym $mod+shift+0 move container to workspace $ws10 +bindsym $mod+shift+minus move container to workspace $ws11 +bindsym $mod+shift+equal move container to workspace $ws12 diff --git a/.config/nvim/.editorconfig b/.config/nvim/.editorconfig new file mode 100644 index 0000000..26c4c89 --- /dev/null +++ b/.config/nvim/.editorconfig @@ -0,0 +1,11 @@ +[*] +charset = UTF-8 +end_of_line = LF +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = tab +indent_size = tab + +[*.lua] +indent_style = tab +indent_size = tab diff --git a/.config/nvim/.gitignore b/.config/nvim/.gitignore new file mode 100644 index 0000000..6cf9d4a --- /dev/null +++ b/.config/nvim/.gitignore @@ -0,0 +1,5 @@ +.luarc.json +nvim + +*.vim +lazy-lock.json diff --git a/.config/nvim/LICENSE.md b/.config/nvim/LICENSE.md new file mode 100644 index 0000000..9cf1062 --- /dev/null +++ b/.config/nvim/LICENSE.md @@ -0,0 +1,19 @@ +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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 OR COPYRIGHT HOLDERS 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. diff --git a/.config/nvim/README.md b/.config/nvim/README.md new file mode 100644 index 0000000..a3b9fea --- /dev/null +++ b/.config/nvim/README.md @@ -0,0 +1,13 @@ +# Quinn's NeoVim configuration +### Required/Recommended tools: +- cURL +- git +- C compiler +- Rust toolchain +- lf +- fd +- clang-format +- rustfmt +- shfmt +- yq +- lua5.1 diff --git a/.config/nvim/docs/TODO.md b/.config/nvim/docs/TODO.md new file mode 100644 index 0000000..0d0613a --- /dev/null +++ b/.config/nvim/docs/TODO.md @@ -0,0 +1,10 @@ +# TODO +- [X] keybind to edit multiple lines at once (have multiple cursors) +- [ ] keybind to rename symbol +- [ ] have TAB in insert mode automatically bring me up to the right indentation. +- [X] debugger + - [X] launch on f5 + - [x] breakpoints + - [X] can set breakpoints + - [X] breakpoints look nice +- [ ] plugin for markdown to make taking notes like these easier? diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua new file mode 100644 index 0000000..c09e190 --- /dev/null +++ b/.config/nvim/init.lua @@ -0,0 +1,11 @@ +vim.g.mapleader = ' ' +vim.g.maplocalleader = ' ' + +Autocmd = vim.api.nvim_create_autocmd +Map = vim.keymap.set + +---@class userdata +---@field palette GruvboxPalette +_G.userdat = {} + +require('config') diff --git a/.config/nvim/lua/config/autocmds.lua b/.config/nvim/lua/config/autocmds.lua new file mode 100644 index 0000000..742b4c2 --- /dev/null +++ b/.config/nvim/lua/config/autocmds.lua @@ -0,0 +1,73 @@ +-- highlight when yanking text +Autocmd('TextYankPost', { + desc = 'highlight when yanking text', + group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }), + callback = function() + vim.highlight.on_yank() + end, +}) + +-- disable new line comment +Autocmd("BufEnter", { + desc = "disable bew line comment", + callback = function() + vim.opt.formatoptions:remove({ "c", "r", "o" }) + end, +}) + +-- go to last location when opening a buffer +Autocmd("BufReadPost", { + desc = "go to last location when opening a buffer", + callback = function() + local mark = vim.api.nvim_buf_get_mark(0, '"') + local lcount = vim.api.nvim_buf_line_count(0) + if mark[1] > 0 and mark[1] <= lcount then + pcall(vim.api.nvim_win_set_cursor, 0, mark) + end + end, +}) + +-- close certain windows with q +Autocmd('FileType', { + desc = 'close certain windows with q', + pattern = { 'help', 'man', 'qf', 'query', 'messages', 'netrw' }, + callback = function(evt) + vim.bo[evt.buf].buflisted = false + Map('n', 'q', 'close') + end +}) + +-- disable spellcheck in terminal +Autocmd('TermOpen', { + callback = function() + vim.opt.spell = false + end, +}) + +-- closes the first buffer if it is empty +Autocmd('BufEnter', { + pattern = '*', + callback = function() + local bufs = vim.api.nvim_list_bufs() + + -- check if the first buffer is an empty one + if #bufs == 0 and vim.api.nvim_get_option_value('buftype', { buf = bufs[1] }) and vim.api.nvim_buf_get_name(bufs[1]) then + vim.api.nvim_buf_delete(bufs[1], {}) + end + end, +}) + +---@type table +local filemap = { + ['*.h'] = 'c', + ['*/i3/**.conf'] = 'i3config' +} + +for pat, file in pairs(filemap) do + Autocmd('BufRead', { + pattern = pat, + callback = function() + vim.bo.filetype = file + end + }) +end diff --git a/.config/nvim/lua/config/init.lua b/.config/nvim/lua/config/init.lua new file mode 100644 index 0000000..9d40f6f --- /dev/null +++ b/.config/nvim/lua/config/init.lua @@ -0,0 +1,4 @@ +require('config.opts') +require('config.maps') +require('config.autocmds') +require('config.lazy') diff --git a/.config/nvim/lua/config/lazy.lua b/.config/nvim/lua/config/lazy.lua new file mode 100644 index 0000000..8db02aa --- /dev/null +++ b/.config/nvim/lua/config/lazy.lua @@ -0,0 +1,24 @@ +-- bootstrap lazy +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' + local out = vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath } + if vim.v.shell_error ~= 0 then + vim.api.nvim_echo({ + { 'Failed to clone lazy.nvim:\n', 'ErrorMsg' }, + { out, 'WarningMsg' }, + }, true, {}) + return 1 + end +end +vim.opt.rtp:prepend(lazypath) + +require('lazy').setup({ + change_detection = { enabled = false }, + defaults = { + lazy = true, + }, + spec = { { import = 'plugin' } }, +}) + +Map('n', 'L', 'Lazy', { desc = 'open Lazy' }) diff --git a/.config/nvim/lua/config/maps.lua b/.config/nvim/lua/config/maps.lua new file mode 100644 index 0000000..3349c32 --- /dev/null +++ b/.config/nvim/lua/config/maps.lua @@ -0,0 +1,45 @@ +-- unmap arrow keys in non-insert modes +Map({ 'n', 'v' }, '', '') +Map({ 'n', 'v' }, '', '') +Map({ 'n', 'v' }, '', '') +Map({ 'n', 'v' }, '', '') + +-- tab management / navigation +Map('n', '', 'enew', { desc = 'create a new tab' }) + +-- for help exiting certain modes +Map({ 'n', 'i' }, '', 'nohlsearch', { desc = 'cancel search highlighting and escape' }) +Map('t', '', '', { desc = 'exit terminal mode' }) + +-- window management +Map('n', '', 'wincmd s', { desc = 'horizontal split' }) +Map('n', '', 'wincmd v', { desc = 'vertical split' }) +Map('n', '', 'wincmd h', { desc = 'move focus to the left window' }) +Map('n', '', 'wincmd l', { desc = 'move focus to the right window' }) +Map('n', '', 'wincmd j', { desc = 'move focus to the lower window' }) +Map('n', '', 'wincmd k', { desc = 'move focus to the upper window' }) +Map('n', '', 'wincmd H', { desc = 'move window to left' }) +Map('n', '', 'wincmd L', { desc = 'move window to right' }) +Map('n', '', 'wincmd K', { desc = 'move window to top' }) +Map('n', '', 'wincmd J', { desc = 'move window to bottom' }) + +-- diagnostic / lsp key bindings +Map('n', 'K', vim.lsp.buf.hover, { desc = 'symbol hover' }) +Map('n', '', vim.lsp.buf.rename, { desc = 'rename symbol' }) +Map('n', 'lm', vim.diagnostic.open_float, { desc = 'view line\'s diagnostic messages' }) +Map('n', 'q', vim.lsp.buf.code_action, { desc = 'view quickfix list' }) + +-- smart tabulation +Map('i', '', function() + local _, col = unpack(vim.api.nvim_win_get_cursor(0)) -- get cursor position + local isindent = vim.api.nvim_get_current_line():sub(1, col):match('^%s*$') + local tabexpnd = vim.bo.expandtab + local tabwidth = vim.bo.shiftwidth > 0 and vim.bo.shiftwidth or vim.bo.tabstop + + if not tabexpnd and isindent then + return '\t' + else + local spaces = tabwidth - col % tabwidth + return string.rep(' ', spaces == 0 and tabwidth or spaces) + end +end, { expr = true, desc = "smart tabulation" }) diff --git a/.config/nvim/lua/config/opts.lua b/.config/nvim/lua/config/opts.lua new file mode 100644 index 0000000..13aca54 --- /dev/null +++ b/.config/nvim/lua/config/opts.lua @@ -0,0 +1,59 @@ +local o = vim.opt + +-- set options +o.clipboard = "unnamedplus" -- keep the clipboard in sync with the one provided by the OS +o.termguicolors = true -- allows for colour in the terminal +o.number = true -- show line numbers +o.cursorline = true -- highlight the current line +o.cursorcolumn = false -- highlight the current column +o.dir = vim.fn.stdpath('cache') .. '/swp' -- swap directory location for recovery +o.sessionoptions = 'buffers,curdir,folds,help,localoptions,tabpages,terminal' +o.expandtab = false -- whether tabs are expanded to spaces (overridden by .editorconfig) +o.diffopt = 'internal,filler,closeoff,linematch:60' -- diff visualisation +o.foldenable = true -- whether folding is enabled +o.wrap = false -- whether to wrap text to a new line when it goes off-screen +o.breakindent = true -- wrapped lines start at the same location as the start of the line +o.list = true -- shows invisible characters +o.listchars = { -- whitespace characters + eol = nil, + trail = '~', + extends = nil, + precedes = '<', + tab = '•-', + space = '·', + nbsp = '␣', +} +o.mouse = 'nv' -- which modes the mouse is enabled in 'a:all' +o.relativenumber = true -- whether line numbers are relative to the cursor +o.scrolloff = 10 -- minimal number of screen lines to keep above and below the cursor +o.showtabline = 2 -- whether to show the tab line +o.signcolumn = 'yes' -- always show the signcolumn, otherwise it shifts text all the time +o.tabstop = 8 -- visual spaces per tab +o.softtabstop = 8 -- spaces inserted per tab in insert mode +o.shiftwidth = 8 -- spaces for auto-indent +o.smartindent = true -- behave a bit more nuanced with when to indent +o.ignorecase = true -- whether case should be ignored whilst searching +o.smartcase = true -- overrides the above option if contains capital letters +o.inccommand = 'split' -- split|nosplit whether substitutions should appear whilst typing. +o.splitbelow = true -- force all horizontal splits below the current window +o.splitright = true -- force all vertical splits to the right of this window +o.showmode = false -- don't show mode as this is already in the status line +o.undodir = vim.fn.stdpath('cache') .. '/undo' -- directory for undo files +o.undofile = true -- for saving the undo history +o.undolevels = 1024 -- the amount of changes that can be undone +o.timeoutlen = 300 -- number of MS to wait for a mapped sequence to complete +o.ttimeoutlen = 0 -- number of MS to wait for a key sequence to complete +o.updatetime = 250 -- number of MS of nothing typed to write a swap file to disk. +o.spell = true -- whether spell checking is enabled +o.spelllang = 'en_gb,nl' -- set the spell languages +o.spellfile = vim.fn.stdpath('config') .. '/spell/user.utf-8.add' + +vim.diagnostic.config({ + underline = true, -- use underline for diagnostics + virtual_text = true, -- shows diagnostics at the end of the line + virtual_lines = false, -- shows one diagnostic per line + severity_sort = true, -- sort diagnostics by severity + update_in_insert = true, -- update diagnostics whilst in insert mode + float = true, -- options for floating windows + signs = true, +}) diff --git a/.config/nvim/lua/plugin/auto-session.lua b/.config/nvim/lua/plugin/auto-session.lua new file mode 100644 index 0000000..9af1e77 --- /dev/null +++ b/.config/nvim/lua/plugin/auto-session.lua @@ -0,0 +1,44 @@ +---@type LazySpec +return { + "rmagatti/auto-session", + lazy = false, + priority = 100, + ---@module "auto-session" + ---@type AutoSession.Config + opts = { + enabled = true, + auto_save = true, + auto_create = true, + auto_restore = true, + auto_restore_last_session = false, + cwd_change_handling = true, + single_session_mode = false, + close_unsupported_windows = true, + suppressed_dirs = { '~/', '~/software/', '~/downloads/', '~/desktop/', '/etc/' }, + close_filetypes_on_save = { 'checkhealth', 'man', 'oil' }, + bypass_save_filetypes = { 'netrw', 'oil' }, + + auto_delete_empty_sessions = true, + purge_after_minutes = 14 * 24 * 60, + + lazy_support = true, + legacy_cmds = false, + args_allow_single_directory = true, + args_allow_files_auto_save = false, + + -- log_level = 'debug', + show_auto_restore_notif = true, + }, + init = function() + local path = vim.fn.argv(0) + if not path or type(path) ~= 'string' then return end + + local realpath = vim.uv.fs_realpath(path) + if not realpath then return end + + if vim.fn.isdirectory(realpath) ~= 1 then return end + vim.fn.chdir(realpath) + + vim.notify("loaded directory: '" .. realpath .. "'", vim.log.levels.INFO) + end, +} diff --git a/.config/nvim/lua/plugin/autopairs.lua b/.config/nvim/lua/plugin/autopairs.lua new file mode 100644 index 0000000..d3d275f --- /dev/null +++ b/.config/nvim/lua/plugin/autopairs.lua @@ -0,0 +1,32 @@ +---@type LazySpec +return { { + 'windwp/nvim-autopairs', -- automatically inserts closing brackets + event = { 'BufReadPre', 'BufNewFile' }, + opts = { + enable_moveright = true, -- moves the cursor over existing pairs instead of inserting duplicates + check_ts = true, -- whether to check treesitter for specific nodes + ts_config = {} + }, + config = function(_, opts) + local autopairs = require 'nvim-autopairs' + autopairs.setup(opts) + + -- customise the rule for [] brackets so it doesn't close when typing ANSI escape codes + local rule = autopairs.get_rule '[' + if rule then + rule:with_pair(function(opt) + local ei = math.max(1, opt.col - 1) -- get the end-index + local prev_oct = opt.line:sub(math.max(1, opt.col - 4), ei) -- get the range of an octal escape code + local prev_hex = opt.line:sub(math.max(1, opt.col - 4), ei) -- get the range of a hexadecimal escape code + local prev_cha = opt.line:sub(math.max(1, opt.col - 2), ei) -- get the range of a character escape code + + -- check whether we can't match any of the patterns, + -- if so return true, otherwise return false (whether to insert a pair) + return (prev_oct ~= [[\033]] and prev_hex ~= [[\x1b]] and prev_cha ~= [[\e]]) + end) + else + vim.notify('could not add a rule for not auto-closing [ when typing an ANSI escape code', + vim.log.levels.WARN) + end + end, +} } diff --git a/.config/nvim/lua/plugin/blink-cmp.lua b/.config/nvim/lua/plugin/blink-cmp.lua new file mode 100644 index 0000000..61424fa --- /dev/null +++ b/.config/nvim/lua/plugin/blink-cmp.lua @@ -0,0 +1,69 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'saghen/blink.cmp', + event = 'InsertEnter', + version = '*', + build = 'cargo build --release', + dependencies = { + 'saghen/blink.compat', + }, + ---@module 'blink.cmp' + ---@type blink.cmp.Config + opts = { + keymap = { + preset = 'none', + [''] = { 'accept', 'fallback' }, -- accept the snippet + [''] = { 'show', 'show_documentation', 'hide_documentation' }, -- toggle auto-cmp manually + [''] = { 'show_signature', 'hide_signature', 'fallback' }, -- toggle signature + [''] = { 'select_next', 'fallback' }, -- next item + [''] = { 'select_prev', 'fallback' }, -- previous item + [''] = { 'scroll_documentation_down', 'fallback' }, -- forwards into the docs + [''] = { 'scroll_documentation_up', 'fallback' }, -- backwards into the docs + [''] = { 'cancel', 'fallback' }, -- keybind for cancelling completion + }, + snippets = { preset = 'luasnip' }, + sources = { + default = { 'lsp', 'path', 'snippets' }, + }, + completion = { + menu = { + auto_show = true, -- whether to automatically show the window when new completion items are available + border = 'rounded', + draw = { + columns = { { "kind_icon" }, { "label", "label_description", gap = 1 }, { 'kind' } }, + treesitter = { 'lsp', 'snippets' }, + }, + }, + documentation = { + auto_show = true, -- whether documentation is automatically shown when selecting a completion item + auto_show_delay_ms = 250, + treesitter_highlighting = true, + window = { border = "rounded" }, + }, + list = { selection = { preselect = true, auto_insert = true } }, + trigger = { + show_on_insert_on_trigger_character = true, + show_on_accept_on_trigger_character = true, + show_in_snippet = false, + }, + ghost_text = { + enabled = true, + show_with_selection = false, -- whether the ghost text is shown when an item is selected + show_without_selection = true, -- whether the ghost text is shown when no item is selected + show_with_menu = true, -- show ghost text when the menu is open + show_without_menu = true, -- show ghost text when the menu is closed + } + }, + fuzzy = { + use_proximity = true, + frecency = { enabled = true, }, + prebuilt_binaries = { + download = false, -- we are building from source + } + } + }, + config = function(_, opts) + require("blink.cmp").setup(opts) + end +} } diff --git a/.config/nvim/lua/plugin/bufferline.lua b/.config/nvim/lua/plugin/bufferline.lua new file mode 100644 index 0000000..022ad2d --- /dev/null +++ b/.config/nvim/lua/plugin/bufferline.lua @@ -0,0 +1,29 @@ +---@type LazySpec +return { { + 'akinsho/bufferline.nvim', -- shows the opened buffers + event = 'VeryLazy', + dependencies = { 'nvim-tree/nvim-web-devicons', }, + ---@type bufferline.UserConfig + opts = { + options = { + mode = 'buffers', + separator_style = '', + sort_by = 'directory', + diagnostics = 'nvim_lsp', + diagnostics_indicator = function(c, _, _, _) + return '(' .. c .. ')' + end, + }, + }, + config = function(_, opts) + require('bufferline').setup(opts) + + Map('n', '', 'BufferLineCycleNext', { desc = 'switch to the next tab' }) + Map('n', '', 'BufferLineCyclePrev', { desc = 'switch to the previous tab' }) + + Map('n', 'wch', 'BufferLineCloseLeft', { desc = 'close the tabs on the left' }) + Map('n', 'wcl', 'BufferLineCloseRight', { desc = 'close the tabs on the right' }) + Map('n', 'wcw', 'BufferLineCloseOthers', + { desc = 'close all tabs except the current one' }) + end, +} } diff --git a/.config/nvim/lua/plugin/conform.lua b/.config/nvim/lua/plugin/conform.lua new file mode 100644 index 0000000..65edfa9 --- /dev/null +++ b/.config/nvim/lua/plugin/conform.lua @@ -0,0 +1,38 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'stevearc/conform.nvim', -- allows you to format a buffer + event = { 'BufWritePre' }, + cmd = { 'ConformInfo' }, + keys = { + { + 'f', + function() + require('conform').format { async = true, lsp_format = 'fallback' } -- execute the formatter + -- vim.cmd [[keepjumps keeppatterns %s/\s\+$//e]] -- removes trailing whitespace + end, + mode = 'n', + desc = '[f]ormat buffer', + }, + }, + ---@type conform.setupOpts + opts = { + notify_on_error = true, + formatters_by_ft = { + c = { 'clang-format' }, + h = { 'clang-format' }, + cpp = { 'clang-format' }, + hpp = { 'clang-format' }, + glsl = { 'clang-format', lsp_format = "first" }, + typescript = { 'clang-format', lsp_format = "first" }, + css = { 'clang-format' }, + rust = { 'rustfmt' }, + sh = { 'shfmt' }, + python = { 'isort' }, + -- json = { 'jq' }, + -- yaml = { 'yq' }, + toml = { 'yq' }, + xml = { 'yq' }, + }, + } +} } diff --git a/.config/nvim/lua/plugin/gitsigns.lua b/.config/nvim/lua/plugin/gitsigns.lua new file mode 100644 index 0000000..c75ea5f --- /dev/null +++ b/.config/nvim/lua/plugin/gitsigns.lua @@ -0,0 +1,54 @@ +---@type LazySpec +return { { + 'lewis6991/gitsigns.nvim', -- adds git signs to the signcolumn + event = 'VeryLazy', + opts = { + signs_staged_enable = true, -- whether staged statuses are enabled + signcolumn = true, -- the signs enable/disable based on the signcolumn state + current_line_blame = true, -- show the blame of the current line + current_line_blame_opts = { + delay = 50, -- delay in MS before blame is shown + ignore_whitespace = true, -- whether to ignore whitespace + use_focus = true, -- whether to only enable when the buffer is in focus + }, + signs = { -- signs when working + add = { text = '+' }, + change = { text = '~' }, + delete = { text = '_' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + untracked = { text = '┆' }, + }, + signs_staged = { -- signs when staged + add = { text = 'A' }, + change = { text = 'M' }, + delete = { text = 'D' }, + topdelete = { text = 'D' }, + changedelete = { text = 'M' }, + untracked = { text = 'U' }, + }, + attach_to_untracked = true, -- shows untracked files' signcolumn + }, + config = function(_, opts) + require('gitsigns').setup(opts) + + local palette = _G.userdat.palette + local bg = vim.api.nvim_get_hl(0, { name = 'SignColumn' }).bg + for n, fg in pairs { + GitSignsAdd = palette.bright_green, + GitSignsChange = palette.bright_orange, + GitSignsDelete = palette.bright_red, + GitSignsTopdelete = palette.bright_red, + GitSignsChangedelete = palette.bright_orange, + GitSignsUntracked = palette.bright_aqua, + GitSignsStagedAdd = palette.neutral_green, + GitSignsStagedChange = palette.neutral_orange, + GitSignsStagedDelete = palette.neutral_red, + GitSignsStagedTopDelete = palette.neutral_red, + GitSignsStagedChangedelete = palette.neutral_orange, + GitSignsStagedUntracked = palette.neutral_aqua, + } do + vim.api.nvim_set_hl(0, n, { fg = fg, bg = bg }) + end + end, +} } diff --git a/.config/nvim/lua/plugin/gruvbox.lua b/.config/nvim/lua/plugin/gruvbox.lua new file mode 100644 index 0000000..7fbcc93 --- /dev/null +++ b/.config/nvim/lua/plugin/gruvbox.lua @@ -0,0 +1,31 @@ +---@type LazySpec +return { { + 'ellisonleao/gruvbox.nvim', + lazy = false, + dependencies = { 'johnfrankmorgan/whitespace.nvim' }, + priority = 1000, + ---@type GruvboxConfig + opts = { + styles = { + comments = { italic = true } + } + }, + config = function(_, opts) + local colour = require('gruvbox') + colour.setup(opts) + vim.cmd.colorscheme('gruvbox') + _G.userdat.palette = colour.palette + + -- non-essential configuration should be put in here + Autocmd('VimEnter', { + callback = + function() + -- spell highlight must be grey + for _, spell in pairs { 'SpellBad', 'SpellCap', 'SpellRare', 'SpellLocal' } do + vim.api.nvim_set_hl(0, spell, + { fg = nil, bg = nil, sp = _G.userdat.palette.gray, undercurl = true }) + end + end + }) + end +} } diff --git a/.config/nvim/lua/plugin/lazydev.lua b/.config/nvim/lua/plugin/lazydev.lua new file mode 100644 index 0000000..3e9ce68 --- /dev/null +++ b/.config/nvim/lua/plugin/lazydev.lua @@ -0,0 +1,12 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'folke/lazydev.nvim', -- provides the lua LSP for the neovim config. + event = 'VeryLazy', + ft = 'lua', + opts = { + library = { + { path = '${3rd}/luv/library', words = { 'vim%.uv' } }, -- load luvit types when the `vim.uv` word is found + }, + }, +}, } diff --git a/.config/nvim/lua/plugin/lf-nvim.lua b/.config/nvim/lua/plugin/lf-nvim.lua new file mode 100644 index 0000000..faf2b97 --- /dev/null +++ b/.config/nvim/lua/plugin/lf-nvim.lua @@ -0,0 +1,21 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'lmburns/lf.nvim', + lazy = false, + dependencies = { 'akinsho/toggleterm.nvim' }, + ---@module 'lf' + ---@type Lf.Config + opts = { + direction = 'float', + border = 'rounded', + }, + config = function(_, opts) + vim.g.lf_netrw = 1 + + local lf = require('lf') + lf.setup(opts) + + Map({ 'n' }, 'o', lf.start, { desc = 'Shows the LF window' }) + end +} } diff --git a/.config/nvim/lua/plugin/lsp_signature.lua b/.config/nvim/lua/plugin/lsp_signature.lua new file mode 100644 index 0000000..684c6ba --- /dev/null +++ b/.config/nvim/lua/plugin/lsp_signature.lua @@ -0,0 +1,5 @@ +---@type LazySpec +return { { + 'ray-x/lsp_signature.nvim', + opts = { always_trigger = false } +} } diff --git a/.config/nvim/lua/plugin/lspconfig.lua b/.config/nvim/lua/plugin/lspconfig.lua new file mode 100644 index 0000000..69e115e --- /dev/null +++ b/.config/nvim/lua/plugin/lspconfig.lua @@ -0,0 +1,51 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'neovim/nvim-lspconfig', + event = { "BufReadPre", "BufNewFile" }, + dependencies = { 'saghen/blink.cmp' }, + ---@type table + opts = { + ['clangd'] = true, + ['ccls'] = false, + ['glsl_analyzer'] = true, + ['rust_analyzer'] = true, + ['omnisharp'] = false, + ['lua_ls'] = true, + + ['html'] = true, + ['cssls'] = true, + ['ts_ls'] = true, + + ['jsonls'] = true, + ['yamlls'] = { + settings = { + yaml = { + schemas = { + ["https://json.schemastore.org/github-workflow.json"] = + "/.github/workflows/*", + ["https://json.schemastore.org/clang-format"] = ".clang-format", + ["https://json.schemastore.org/clang-tidy"] = ".clang-tidy", + }, + }, + }, + }, + }, + ---@param opts table + config = function(_, opts) + -- store the default capabilities + local capabilities = require('blink.cmp').get_lsp_capabilities() + + -- enable the LSP + for server, config in pairs(opts) do + if type(config) == 'boolean' then + vim.lsp.enable(server, config) + else + vim.lsp.enable(server, true) + vim.lsp.config[server] = vim.tbl_deep_extend('force', {}, vim.lsp.config[server], + config or {}) + end + vim.lsp.config[server].capabilities = capabilities + end + end +} } diff --git a/.config/nvim/lua/plugin/luasnip.lua b/.config/nvim/lua/plugin/luasnip.lua new file mode 100644 index 0000000..204cf60 --- /dev/null +++ b/.config/nvim/lua/plugin/luasnip.lua @@ -0,0 +1,5 @@ +return { { + 'L3MON4D3/LuaSnip', + build = 'make install_jsregexp', + version = "v2.*", +} } diff --git a/.config/nvim/lua/plugin/mini.lua b/.config/nvim/lua/plugin/mini.lua new file mode 100644 index 0000000..11c3562 --- /dev/null +++ b/.config/nvim/lua/plugin/mini.lua @@ -0,0 +1,71 @@ +---@type LazySpec +return { { + 'echasnovski/mini.nvim', + config = function() + require('mini.ai').setup() + require('mini.surround').setup() + require('mini.operators').setup() + + require('mini.indentscope').setup({ + symbol = '¦', + draw = { + delay = 50, -- delay in MS before writing the indicator + animation = require('mini.indentscope').gen_animation.none(), + }, + options = { + try_as_border = false, + }, + }) + vim.api.nvim_set_hl(0, 'MiniIndentscopeSymbol', { fg = _G.userdat.palette.dark2, bg = nil }) + + require('mini.move').setup({ + mappings = { + -- move visual selection in visual mode + left = '', + down = '', + up = '', + right = '', + + -- move current line in normal mode + line_left = '', + line_down = '', + line_up = '', + line_right = '', + }, + options = { + reindent_linewise = true, -- automatically re-indent selection during line vertical move + }, + }) + + require('mini.statusline').setup({ + content = { + active = function() + local mode, mode_hl = MiniStatusline.section_mode({ trunc_width = 120 }) + local git = MiniStatusline.section_git({ trunc_width = 40 }) + local diff = MiniStatusline.section_diff({ trunc_width = 75 }) + local diagnostics = MiniStatusline.section_diagnostics({ trunc_width = 75 }) + local lsp = MiniStatusline.section_lsp({ trunc_width = 75 }) + local filename = MiniStatusline.section_filename({ trunc_width = 140 }) + local fileinfo = MiniStatusline.section_fileinfo({ trunc_width = 120 }) + + return MiniStatusline.combine_groups({ + { hl = mode_hl, strings = { mode } }, + { hl = 'MiniStatuslineDevinfo', strings = { git, diff, diagnostics, lsp } }, + '%<', -- general truncation point + { hl = 'MiniStatuslineFilename', strings = { filename } }, + '%=', -- align right + { hl = 'MiniStatuslineFileInfo', strings = { fileinfo } }, + { hl = mode_hl, strings = { '%3l:%-3c' } } + }) + end, + inactive = function() + return MiniStatusline.combine_groups({ + {}, + }) + end + }, + use_icons = true, + set_vim_settings = true, + }) + end +} } diff --git a/.config/nvim/lua/plugin/nvim-lint.lua b/.config/nvim/lua/plugin/nvim-lint.lua new file mode 100644 index 0000000..295f0de --- /dev/null +++ b/.config/nvim/lua/plugin/nvim-lint.lua @@ -0,0 +1,59 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'mfussenegger/nvim-lint', + event = { 'BufWritePost', 'BufReadPost', 'TextChanged' }, + ---@module 'lint' + opts = { + ---@type table + linters_by_ft = { + c = { 'clangtidy' }, + cpp = { 'clangtidy' }, + sh = { 'shellcheck' }, + glsl = { 'glslang' }, + }, + linters = { + glslang = { + cmd = 'glslangValidator', + stdin = false, + args = { '-C' }, + ignore_exitcode = true, + parser = function(output) + local diags = {} + for _, line in ipairs(vim.split(output, '\n')) do + local f, lnum, sev, msg = line:match( + '^([^:]+):(%d+):%s+([^:]+):%s+(.+)$') -- file:line: severity: message + if not f then sev, f, lnum, msg = line:match( + '^(%w+):%s+([^:]+):(%d+):%s+(.+)$') end -- severity: file:line: message + + if lnum then + local s = sev:lower() == 'error' + and vim.diagnostic.severity.ERROR + or vim.diagnostic.severity.WARN + table.insert(diags, { + lnum = tonumber(lnum) - 1, + col = 0, + message = msg, + source = 'glslang', + severity = s + }) + end + end + return diags + end + } + } + }, + config = function(_, opts) + local lint = require('lint') + lint.linters_by_ft = opts.linters_by_ft + + for name, linter in pairs(opts.linters) do + lint.linters[name] = linter + end + + -- autocommand for linting + Autocmd({ 'BufWritePost', 'BufWinEnter', 'TextChanged' }, + { callback = function() lint.try_lint() end }); + end +} } diff --git a/.config/nvim/lua/plugin/nvim-treesitter.lua b/.config/nvim/lua/plugin/nvim-treesitter.lua new file mode 100644 index 0000000..6e65483 --- /dev/null +++ b/.config/nvim/lua/plugin/nvim-treesitter.lua @@ -0,0 +1,74 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'nvim-treesitter/nvim-treesitter', -- highlight, edit, and navigate code + event = 'BufReadPre', + build = ':TSUpdate', + main = 'nvim-treesitter.configs', -- set main module to use for opts + opts = { + ensure_installed = { + 'bash', 'c', 'make', 'rust', 'diff', + 'markdown', 'markdown_inline', 'latex', + 'vim', 'vimdoc', 'lua', 'luadoc', 'regex', + }, + auto_install = true, -- auto-install languages that are not installed + highlight = { + enable = true, + additional_vim_regex_highlighting = { 'ruby' }, -- some languages depend on vim's regex highlighting system for indent rules + }, + indent = { enable = true, disable = { 'ruby' } }, + }, + config = function(_, opts) + require('nvim-treesitter.configs').setup(opts) + + -- set the keybind for appending in front of a comment, rather than behind. + Map('n', 'A', function() + local ts = vim.treesitter -- get reference to treesitter + local buf = vim.api.nvim_get_current_buf() -- get the current buffer id + local row, col = unpack(vim.api.nvim_win_get_cursor(0)) -- get cursor position + + -- ensure the parser exists + local res = nil + repeat + -- get the parser + if not ts.language.get_lang(vim.bo[buf].filetype) then break end + local parser = ts.get_parser(buf, nil, { error = false }) + if not parser then break end + + -- query the buffer using the parser + local root = parser:parse()[1]:root() + local ok, dat = pcall(ts.query.parse, parser:lang(), [[(comment) @comment]]) + if not ok or not dat then break end + + -- set the result + res = { query = dat, root = root } + until true + + -- check if we successfully made a query + if res then + -- loop through the captures from the query + for _, node in res.query:iter_captures(res.root, buf, row - 1, row) do + -- ensure the comment is on the same row as the cursor and after the cursor's column + local srow, scol, _, _ = node:range() -- extract the starting row and starting column + if srow ~= row - 1 or col >= scol then goto continue end + + -- get the line text and remove trailing whitespace + local txt = vim.api.nvim_buf_get_lines(buf, srow, srow + 1, true)[1]:sub(0, scol) + txt = txt:gsub("%s*$", "") + local len = txt:len() + + -- check if we found a match + if len > 0 then + vim.api.nvim_win_set_cursor(0, { row, len }) + vim.cmd [[startinsert]] + return + end + ::continue:: -- lua is stupid + end + end + + -- no comment start was found, behave like normal (moves cursor to the end of the line) + vim.cmd [[startinsert!]] + end, { desc = 'append end of line' }) + end, +} } diff --git a/.config/nvim/lua/plugin/render-markdown.lua b/.config/nvim/lua/plugin/render-markdown.lua new file mode 100644 index 0000000..4797814 --- /dev/null +++ b/.config/nvim/lua/plugin/render-markdown.lua @@ -0,0 +1,13 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'MeanderingProgrammer/render-markdown.nvim', + dependencies = { 'nvim-treesitter/nvim-treesitter', 'echasnovski/mini.nvim' }, + ---@module 'render-markdown' + ---@type render.md.UserConfig + opts = { + completions = { + blink = { enabled = true } + } + } +} } diff --git a/.config/nvim/lua/plugin/snacks.lua b/.config/nvim/lua/plugin/snacks.lua new file mode 100644 index 0000000..5a35c14 --- /dev/null +++ b/.config/nvim/lua/plugin/snacks.lua @@ -0,0 +1,83 @@ +---@module 'snacks' +---@module 'lazy' +---@type LazySpec +return { { -- provides quality of life features for neovim + 'folke/snacks.nvim', + priority = 1000, + lazy = false, + ---@type snacks.Config + opts = { + animate = { enabled = false }, -- efficient animations including over 45 easing functions (library) + bigfile = { enabled = false }, -- deal with big files + bufdelete = { enabled = false }, -- delete buffers without disrupting window layout + dashboard = { enabled = false }, -- beautiful declarative dashboards + debug = { enabled = false }, -- pretty inspect & backtraces for debugging + dim = { enabled = false }, -- focus on the active scope by dimming the rest + explorer = { enabled = false }, -- a file explorer (picker in disguise) + git = { enabled = false }, -- git utilities + gitbrowse = { enabled = false }, -- open the current file, branch, commit, or repo in a browser (e.g. github, gitlab, etc.) + image = { enabled = true }, -- image viewer using kitty graphics protocol + indent = { enabled = false }, -- indent guides and scopes + input = { enabled = false }, -- better vim.ui.input + layout = { enabled = false }, -- window layouts + lazygit = { enabled = false }, -- open lazygit in a float, auto-configure colour scheme and integration with neovim + notifier = { enabled = true }, -- pretty vim.notify + notify = { enabled = true }, -- utility functions to work with neovim's vim.notify + picker = { enabled = false }, -- picker for selecting items + profiler = { enabled = false }, -- neovim lua profiler + quickfile = { enabled = true }, -- when doing nvim somefile.txt, it will render the file as quickly as possible, before loading your plugins. + rename = { enabled = true }, -- LSP-integrated file renaming with support for plugins like and. + scope = { enabled = false }, -- scope detection, text objects and jumping based on treesitter or indent + scratch = { enabled = false }, -- scratch buffers with a persistent file + scroll = { enabled = false }, -- smooth scrolling + statuscolumn = { enabled = false }, -- pretty status column + terminal = { enabled = false }, -- create and toggle floating/split terminals + toggle = { enabled = false }, -- toggle keymaps integrated with which-key icons / colours + util = { enabled = false }, -- utility functions for Snacks (library) + win = { enabled = false }, -- create and manage floating windows or splits + words = { enabled = true }, -- auto-show LSP references and quickly navigate between them + zen = { enabled = false }, -- zen mode; distraction-free coding + }, + keys = { + { '*', function() Snacks.words.jump(-vim.v.count1) end, desc = 'next reference', nowait = true }, + { '#', function() Snacks.words.jump(vim.v.count1) end, desc = 'prev reference', nowait = true }, + { '', function() Snacks.bufdelete() end, desc = 'delete buffer', nowait = true }, + { 'N', function() Snacks.notifier.show_history() end, desc = 'show notification history' }, + { 'U', function() Snacks.picker.undo() end, desc = 'undo tree' }, + { 'gB', function() Snacks.git.blame_line() end, desc = 'git blame line' }, + { 'gb', function() Snacks.picker.git_branches() end, desc = 'git branches' }, + { '@', function() Snacks.picker.lsp_symbols() end, desc = 'workspace symbols' }, + { 'ld', function() Snacks.picker.lsp_definitions() end, desc = 'definition' }, + { 'lr', function() Snacks.picker.lsp_references() end, desc = 'references' }, + { 'li', function() Snacks.picker.lsp_implementations() end, desc = 'implementation' }, + { 'lt', function() Snacks.picker.lsp_type_definitions() end, desc = 'type definition' }, + { '?', function() Snacks.picker.keymaps() end, desc = 'keymaps' }, + { 'gd', function() Snacks.picker.lsp_definitions() end, desc = 'definition' }, + { 'gr', function() Snacks.picker.lsp_references() end, desc = 'references' }, + }, + init = function() + Autocmd("User", { + pattern = 'VeryLazy', + callback = function() + local virt_lines = false; + Snacks.toggle.new({ + id = "virtual_lines", + name = "diagnostics virtual lines", + get = function() return virt_lines end, + set = function(v) + virt_lines = v + vim.diagnostic.config({ virtual_lines = v }) + end, + }):map('tl') + + Snacks.toggle.option('wrap', { name = 'word wrap' }):map('tw') + Snacks.toggle.option('spell', { name = 'spelling' }):map('ts') + Snacks.toggle.inlay_hints():map('th') + end, + }) + end, + ---@param opts snacks.Config + config = function(_, opts) + require('snacks').setup(opts) + end +} } diff --git a/.config/nvim/lua/plugin/telescope.lua b/.config/nvim/lua/plugin/telescope.lua new file mode 100644 index 0000000..77b74af --- /dev/null +++ b/.config/nvim/lua/plugin/telescope.lua @@ -0,0 +1,71 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'nvim-telescope/telescope.nvim', -- fuzzy finder (files, lsp, etc) + event = 'VeryLazy', + branch = '0.1.x', + dependencies = { + { 'nvim-lua/plenary.nvim' }, -- contains lua functions for neovim, apparently + { 'nvim-telescope/telescope-ui-select.nvim' }, -- allows neovim core stuff to enter the telescope picker + { + 'nvim-telescope/telescope-fzf-native.nvim', + build = 'make', -- used for when the plugin is installed/updated + cond = function() return vim.fn.executable 'make' == 1 end, -- condition for whether the plugin should be loaded / installed + }, + }, + opts = { + pickers = { + find_files = { + find_command = { 'fd', '-t', 'f', '-HE', '/.git', '--strip-cwd-prefix' }, + }, + }, + extensions = { + file_browser = { + hijack_netrw = true, + }, + }, + }, + config = function(_, opts) + local tel = require('telescope') + local std = require("telescope.builtin") + local ext = tel.extensions + require('telescope').setup(opts) + + -- load telescope extensions, if they are installed + pcall(tel.load_extension, 'fzf') + pcall(tel.load_extension, 'ui-select') + + -- set the telescope keymaps + Map({ 'n' }, '', std.live_grep, { desc = 'Search by Grep' }) + Map({ 'n' }, '', std.resume, { desc = 'Search Resume' }) + Map({ 'n', 'i' }, '', std.find_files, { desc = 'Search Project' }) + Map({ 'n' }, 'p', std.find_files, { desc = 'Search Project' }) + Map({ 'n' }, 'gf', std.git_status, { desc = 'Search through Git status Files' }) + Map({ 'n' }, 'sq', std.quickfix, { desc = 'Search Quickfix' }) + Map({ 'n' }, 'sh', std.help_tags, { desc = 'Search Help' }) + Map({ 'n' }, 'sk', std.keymaps, { desc = 'Search Keymaps' }) + Map({ 'n' }, 'sf', std.find_files, { desc = 'Search Files' }) + Map({ 'n' }, 'ss', std.builtin, { desc = 'Sarch Select telescope' }) + Map({ 'n' }, 'sw', std.grep_string, { desc = 'Search current Word' }) + Map({ 'n' }, 'sg', std.live_grep, { desc = 'Search by Grep' }) + Map({ 'n' }, 'sd', std.diagnostics, { desc = 'Search Diagnostics' }) + Map({ 'n' }, 'sr', std.resume, { desc = 'Search Resume' }) + Map({ 'n' }, 's.', std.oldfiles, { desc = 'Search recent Files ("." for repeat)' }) + Map({ 'n' }, '', std.buffers, { desc = 'find existing buffers' }) + + -- for fuzzily searching in the current buffer + Map('n', '/', function() + std.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { winblend = 10, previewer = false }) + end, { desc = 'fuzzily search in current buffer' }) + + -- for executing grep + Map('n', 's/', function() + std.live_grep { grep_open_files = true, prompt_title = 'Live Grep in Open Files' } + end, { desc = 'Search in open files' }) + + -- shortcut for searching neovim config files + Map('n', 'sn', function() + std.find_files { cwd = vim.fn.stdpath 'config' } + end, { desc = 'Search Neovim files' }) + end, +} } diff --git a/.config/nvim/lua/plugin/todo-comments.lua b/.config/nvim/lua/plugin/todo-comments.lua new file mode 100644 index 0000000..8374192 --- /dev/null +++ b/.config/nvim/lua/plugin/todo-comments.lua @@ -0,0 +1,22 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'folke/todo-comments.nvim', -- for highlighting TODO and stuff comments + event = 'VeryLazy', + dependencies = { 'nvim-lua/plenary.nvim' }, + ---@module 'todo-comments' + ---@type TodoOptions + opts = { + signs = false, + colors = { + hint = { "Comment" } + }, + }, + config = function(_, opts) + local todo = require 'todo-comments' + todo.setup(opts) + + Map('n', 'st', 'TodoTelescope keywords=TODO,FIX,BUG,WARN', + { desc = '[S]earch [T]odos]' }) + end, +} } diff --git a/.config/nvim/lua/plugin/toggleterm.lua b/.config/nvim/lua/plugin/toggleterm.lua new file mode 100644 index 0000000..113e8a6 --- /dev/null +++ b/.config/nvim/lua/plugin/toggleterm.lua @@ -0,0 +1,53 @@ +---@module 'lazy' +---@type LazySpec +return { { + 'akinsho/toggleterm.nvim', -- allows to toggle the terminal rather than open one in a separate window + event = 'VeryLazy', + ---@type ToggleTermConfig + ---@diagnostic disable-next-line: missing-fields + opts = { open_mapping = [[]] }, + config = function(_, opts) + local tt = require('toggleterm') + local term = require('toggleterm.terminal') + tt.setup(opts) + + local term_lazygit = term.Terminal:new({ cmd = "lazygit", hidden = true, direction = 'float' }) + + -- Set mappings to toggle the above + Map({ 'n' }, 'gg', function() term_lazygit:toggle() end) + + -- Add a keymap for executing makefiles, or launch scripts + Map({ 'n', 't', 'v' }, '', function() + local cwd = vim.fn.getcwd() + local cmd = nil + local launchcfg = cwd .. '/.launch.sh' + + -- If the path is readable, the attached command is executed and no more is checked. + for _, obj in ipairs({ + { launchcfg, launchcfg }, + { cwd .. '/Makefile', 'make -C ' .. cwd }, + { cwd .. '/makefile', 'make -C ' .. cwd }, + }) do + local pat = obj[1] + local exec = obj[2] + if (vim.fn.filereadable(pat) == 1) then + cmd = '\r' .. exec -- use \r to override text if it's present + break + end + end + + -- If cmd still hasn't been set; edit the file + if (not cmd) then + local buf = vim.api.nvim_create_buf(true, false) -- listed, not scratch + vim.api.nvim_set_current_buf(buf) + vim.api.nvim_buf_set_name(buf, launchcfg) + vim.api.nvim_buf_set_text(0, 0, 0, 0, 0, { '#!/usr/bin/env sh', 'exec ' }) + vim.bo.ft = 'sh' + return + end + + -- Execute the command in terminal 1 + tt.exec(cmd, 1, nil, nil, nil, nil, false, true) + end, { desc = 'compile the program using .buildcofig placed in PWD' }) + end +} } diff --git a/.config/nvim/lua/plugin/which-key.lua b/.config/nvim/lua/plugin/which-key.lua new file mode 100644 index 0000000..6fe03f8 --- /dev/null +++ b/.config/nvim/lua/plugin/which-key.lua @@ -0,0 +1,51 @@ +---@type LazySpec +return { { -- displays pending keybinds, helps with remembering keybinds + 'folke/which-key.nvim', + event = 'VeryLazy', + ---@module 'which-key' + ---@type wk.Opts + opts = { + delay = 0, -- delay in MS between pressing a key and opening which-key + icons = { + mappings = true, + keys = { + Up = '', + Down = '', + Left = '', + Right = '', + C = '󰘴', + M = '󰘵', + D = '󰘳', + S = '󰘶', + CR = '󰌑', + Esc = '󱊷', + ScrollWheelUp = '󱕑', + ScrollWheelDown = '󱕐', + NL = '󰌑', + BS = '󰁮', + Space = '󱁐', + Tab = '󰌒', + F1 = '', + F2 = '', + F3 = '', + F4 = '', + F5 = '', + F6 = '', + F7 = '', + F8 = '', + F9 = '', + F10 = '', + F11 = '', + F12 = '', + }, + }, + spec = { -- document the key chains we know about + { 'g', group = 'git' }, + { 's', group = 'search' }, + { 't', group = 'toggle' }, + { 'w', group = 'windows' }, + { 'l', group = 'lsp' }, + { 'wc', group = 'close' }, + }, + }, +} } diff --git a/.config/nvim/spell/nl.utf-8.spl b/.config/nvim/spell/nl.utf-8.spl new file mode 100644 index 0000000..14ec811 Binary files /dev/null and b/.config/nvim/spell/nl.utf-8.spl differ diff --git a/.config/nvim/spell/nl.utf-8.sug b/.config/nvim/spell/nl.utf-8.sug new file mode 100644 index 0000000..3191f5e Binary files /dev/null and b/.config/nvim/spell/nl.utf-8.sug differ diff --git a/.config/nvim/spell/user.utf-8.add b/.config/nvim/spell/user.utf-8.add new file mode 100644 index 0000000..cbbf241 --- /dev/null +++ b/.config/nvim/spell/user.utf-8.add @@ -0,0 +1,56 @@ +binary-formatted +calc +config +const +double-precision +editorconfig +entry-point +github +gitignore +gitlab +half-precision +if +init +inputted +JSON +keymap +LLM +lsp +malloc'd +neovim +non-zero +null-terminated +numlock +nvidia +nvidia-settings +nvim-cmp +OR'd +overworld +parsable +Quinn +re-enable +regex +res +SDL +shader +shaders +single-precision +startup +stderr +stdout +system-wide +TODO +undefine +whitespace +ˣ +xorg +zero-initialise +zero-out +θ +π +τ +φ +ψ +timestamp +tetromino +μs diff --git a/.config/nvim/spell/user.utf-8.add.spl b/.config/nvim/spell/user.utf-8.add.spl new file mode 100644 index 0000000..6177cdf Binary files /dev/null and b/.config/nvim/spell/user.utf-8.add.spl differ