From b0edc8940b9467731e9b87954147ec1461f909e5 Mon Sep 17 00:00:00 2001 From: Amolith Date: Mon, 2 Sep 2024 15:42:45 -0600 Subject: [PATCH] Updates --- dot_Xresources.tmpl | 89 +- dot_config/alacritty/alacritty.toml.tmpl | 2 +- dot_config/doom/config.el.tmpl | 5 +- dot_config/doom/extra/encrypted_mu4e.el.age | 386 ++-- dot_config/encrypted_ytsubscriptions.txt.age | 51 +- dot_config/git/config.tmpl | 3 +- dot_config/isync/encrypted_mbsyncrc.age | 88 +- dot_config/msmtp/encrypted_config.age | 118 +- dot_config/nvim/init.lua | 27 + dot_config/nvim/init.vim.tmpl | 142 -- dot_config/nvim/lua/base/1-options.lua | 93 + dot_config/nvim/lua/base/2-lazy.lua | 75 + dot_config/nvim/lua/base/3-autocmds.lua | 281 +++ dot_config/nvim/lua/base/4-mappings.lua | 1616 +++++++++++++++++ dot_config/nvim/lua/base/health.lua | 270 +++ dot_config/nvim/lua/base/icons/nerd_font.lua | 73 + dot_config/nvim/lua/base/icons/text.lua | 48 + dot_config/nvim/lua/base/utils/init.lua | 307 ++++ dot_config/nvim/lua/base/utils/lsp.lua | 189 ++ dot_config/nvim/lua/base/utils/ui.lua | 321 ++++ .../nvim/lua/plugins/1-base-behaviors.lua | 709 ++++++++ dot_config/nvim/lua/plugins/2-ui.lua | 709 ++++++++ dot_config/nvim/lua/plugins/3-dev-core.lua | 510 ++++++ dot_config/nvim/lua/plugins/4-dev.lua | 901 +++++++++ dot_config/polybar/config.ini.tmpl | 8 +- dot_config/private_zathura/zathurarc.tmpl | 78 +- dot_config/zsh/private_dot_zshrc.tmpl | 24 +- dot_local/bin/executable_startup.tmpl | 2 + .../share/dark-mode.d/executable_swap.sh | 5 +- .../share/light-mode.d/executable_swap.sh | 5 +- private_dot_ssh/encrypted_config.tmpl.age | 81 +- 31 files changed, 6609 insertions(+), 607 deletions(-) create mode 100644 dot_config/nvim/init.lua delete mode 100644 dot_config/nvim/init.vim.tmpl create mode 100644 dot_config/nvim/lua/base/1-options.lua create mode 100644 dot_config/nvim/lua/base/2-lazy.lua create mode 100644 dot_config/nvim/lua/base/3-autocmds.lua create mode 100644 dot_config/nvim/lua/base/4-mappings.lua create mode 100644 dot_config/nvim/lua/base/health.lua create mode 100644 dot_config/nvim/lua/base/icons/nerd_font.lua create mode 100644 dot_config/nvim/lua/base/icons/text.lua create mode 100644 dot_config/nvim/lua/base/utils/init.lua create mode 100644 dot_config/nvim/lua/base/utils/lsp.lua create mode 100644 dot_config/nvim/lua/base/utils/ui.lua create mode 100644 dot_config/nvim/lua/plugins/1-base-behaviors.lua create mode 100644 dot_config/nvim/lua/plugins/2-ui.lua create mode 100644 dot_config/nvim/lua/plugins/3-dev-core.lua create mode 100644 dot_config/nvim/lua/plugins/4-dev.lua diff --git a/dot_Xresources.tmpl b/dot_Xresources.tmpl index faabd9096f6f2094a5ec6a4b230d5969c34506ee..52ff7e72cae899a509504585d8eefed1993b1c58 100644 --- a/dot_Xresources.tmpl +++ b/dot_Xresources.tmpl @@ -6,85 +6,86 @@ Xft.hinting: 1 Xft.antialias: 1 Xft.rgba: rgb -! Xresources has a base colour and a bright variant. The first block contains -! the base colours and the second block contains their bright counterparts. +! Xresources has a base colour and a bright variant. The first of each colour +! pair is "dark" and the second is "bright". In the context of most shell +! themes, "dark" variants seem to be used as foreground accents, while "light" +! variants are highlights behind the default foreground colour. -{{- if eq .theme_variant "dark" }} -! Catppuccin Macchiato -! https://github.com/catppuccin/xresources +{{ if eq .theme_variant "dark" -}} +! Everforest hard dark +! https://github.com/sainnhe/everforest/blob/master/palette.md -*background: #24273A -*foreground: #CAD3F5 +*background: #272E33 +*foreground: #D3C6AA ! black -*color0: #494D64 -*color8: #5B6078 +*color0: #1E2326 +*color8: #7A8478 ! red -*color1: #ED8796 -*color9: #ED8796 +*color1: #E67E80 +*color9: #E67E80 ! green -*color2: #A6DA95 -*color10: #A6DA95 +*color2: #A7C080 +*color10: #A7C080 ! yellow -*color3: #EED49F -*color11: #EED49F +*color3: #DBBC7F +*color11: #DBBC7F ! blue -*color4: #8AADF4 -*color12: #8AADF4 +*color4: #7FBBB3 +*color12: #7FBBB3 ! magenta -*color5: #F5BDE6 -*color13: #F5BDE6 +*color5: #D699B6 +*color13: #D699B6 ! cyan -*color6: #8BD5CA -*color14: #8BD5CA +*color6: #7FBBB3 +*color14: #7FBBB3 ! white -*color7: #B8C0E0 -*color15: #A5ADCB +*color7: #D3C6AA +*color15: #D3C6AA {{- end }} -{{- if eq .theme_variant "light" }} +{{ if eq .theme_variant "light" -}} +! Everforest soft light +! https://github.com/sainnhe/everforest/blob/master/palette.md -! Catppuccin Latte -! https://github.com/catppuccin/xresources - -*background: #EFF1F5 -*foreground: #4C4F69 +*background: #F3EAD3 +*foreground: #5C6A72 ! black *color0: #5C5F77 -*color8: #6C6F85 +*color8: #939f91 ! red -*color1: #D20F39 -*color9: #D20F39 +*color1: #F85552 +*color9: #F85552 ! green -*color2: #40A02B -*color10: #40A02B +*color2: #8DA101 +*color10: #8DA101 ! yellow -*color3: #DF8E1D -*color11: #DF8E1D +*color3: #DFA000 +*color11: #DFA000 ! blue -*color4: #1E66F5 -*color12: #1E66F5 +*color4: #3A94C5 +*color12: #3A94C5 ! magenta -*color5: #EA76CB -*color13: #EA76CB +*color5: #DF69BA +*color13: #DF69BA ! cyan -*color6: #179299 -*color14: #179299 +*color6: #3A94C5 +*color14: #3A94C5 ! white -*color7: #ACB0BE -*color15: #BCC0CC +*color7: #708089 +*color15: #708089 {{- end }} diff --git a/dot_config/alacritty/alacritty.toml.tmpl b/dot_config/alacritty/alacritty.toml.tmpl index 16707eddba9681dcdf2825fcae73e87816cba42c..114b7bad5ae9a4d0146d22b44ead2e5605fa916b 100644 --- a/dot_config/alacritty/alacritty.toml.tmpl +++ b/dot_config/alacritty/alacritty.toml.tmpl @@ -16,7 +16,7 @@ decorations = "None" padding = { x = 7, y = 5 } [font] -normal = { family = "Berkeley Mono", style = "Regular" } +normal = { family = "{{ .font }}", style = "Regular" } [cursor] style = { blinking = "On" } diff --git a/dot_config/doom/config.el.tmpl b/dot_config/doom/config.el.tmpl index 7fece2f70bca563f7431e3db7276997b39ea1d4f..3a7e6aed8d081268d8c328e4f11c70785c4c500b 100644 --- a/dot_config/doom/config.el.tmpl +++ b/dot_config/doom/config.el.tmpl @@ -13,7 +13,8 @@ (load-theme 'everforest-hard-dark t) {{- end }} {{- if eq .theme_variant "light"}} -(load-theme 'everforest-soft-light t) +;;(load-theme 'everforest-soft-light t) +(load-theme 'doom-flatwhite t) {{- end }} (setq display-line-numbers-type t) @@ -145,7 +146,7 @@ (setq tidal-boot-script-path "/usr/share/x86_64-linux-ghc-9.0.2/tidal-1.7.10/BootTidal.hs") -(global-tree-sitter-mode) +(setq +tree-sitter-hl-enabled-modes '(not fundamental-mode)) (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode) (global-wakatime-mode) diff --git a/dot_config/doom/extra/encrypted_mu4e.el.age b/dot_config/doom/extra/encrypted_mu4e.el.age index 553d04ff27eaaacbe4c510ede4fda3cc28844eee..2a2b085c199870458e91f4eb0e36d9e5fd3c3587 100644 --- a/dot_config/doom/extra/encrypted_mu4e.el.age +++ b/dot_config/doom/extra/encrypted_mu4e.el.age @@ -1,196 +1,194 @@ -----BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IEhBV2NqUSBBbkdSeDhT -V3U5R1NiRlFHOERTKzJUODZ5WXQ1ZnFnWGhMeUZzTDV4R2JzeQpZS2I4UzhxOGxh -TzF0STZoNVpFVkdnOGNGMldHQkZkY3ZBaE14SFhQQkI0Ci0+IHBpdi1wMjU2IHBE -YXpSZyBBMG91U0RjeC9iRE9qZjQ5eWg2cnp3bFZ1SHUwbDhHL0NLa0NrL0xtNzZ1 -MwpWM2J4cU01ZlZnUldkajdwQjBUWlFDMHk4RzZYcXJ3R0lQd1IyWHRxZEVRCi0+ -IHJOYWN3Jy1ncmVhc2UgdVs6ID51UgprcVZoVlgrYlgyRWVSN1ppWmZsMDBaMDFJ -bWdqTm16SGNvNHFRcDBFOE0yQmdORGVSNFVGUlV6ejc2SHRaSEhJCmxkcXdvaDly -VFc1RkxaUWZ3bkRoV2V3YmtOcXhhNTRYV2tZawotLS0gblZqK1RBOUEySmp4ci9B -SWxyZFlZNnUzLzZDWHdNM2ZzY0lZU09pZENEcwpIYQ5Hy0EvpPoEymKQdwB3Kzwo -lvE3EYzgWpxHkpiemxwngKE0wB32swTQpiWM/7XRCqZ2lNqY38lzuthz0SyQtGOE -elCIMfi6uB5MUQICai9MnDYx//wOoODJZDRKqhLfjdDb4oRRdZWxbevcGCqu1tr5 -x80fEzwTDAM68Rui+BGii72AAYmVBYZJBSBxAQfH/XjhKP2wYF6OZcVQ3tABosvz -Ro6SkXZnhy10/PzNCIC+yYOHZsAGEMTD5mOdGTT6FyIumAOfTIo1LnC4OTOcrqpz -5TiYvp78admTAQniIGVTk+p5yGH0LBQ7R6LA5RTVHQcOD17fKizOb0VqYQAhfXWI -WT2ayCfyhY6YpY7o56/R89tSUW+i/QO9d6DuQjEC1t7qZ0+XGlF+139trGFXj83R -wP0r++7SMh1DwwAlfRfWk51/SgGrtueSdVPd0M1OgLGL7M+PIMVqV4Iasunwry8X -cDGJSzxPENbe3SUZbmfAXpERZcnm5DB8U8ZW1Tf8gbLCz3q/zHTenf05VHIc8e9Z -82UxWKdC9uw9/ESe3nmoX2MeeI8OCXyNNe1TxohGlag/3QF5Auto4rxm4Q3Kt8un -xZfEy2ujtnpuF1gdhhdPNGmJ0U/lhrUwh8huj7SuunYQDZ1dkH1vd2R5jKQRBzoo -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 -ufHjZUKZaDwFEBf+UPmEcYZxUetDdYUla4OE2W9lJWiuZAkIYudUHLsWrCCnVSVM -+zWl4SDbXAQcaBRE6pa5q9v0qKNpwezcnu5X4+sTXPN76J5C2NnmtKYHZdRk1b+T -RteTlC1nC4CoXin47n/99hVORWpMYB6wlZFeNLqUJrH1KPLI7haCWU6z4CMR0ZGX -X2V/mz1FZkIFCaqieJuAw3CurpLbkB/4AtUVv8HabHc/rR+Tog== +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IEhBV2NqUSBBLy84L0s1 +YlJKMm5YMGM4WFBJYUtOUFpCV0VOUitHbnRwL2JnaTNsRXRzNwpTbjRFU0lhRkxz +REMwUzQyQWlpbFlDbXh4YmQ2QVdUQVRLYzB0UTlVT25ZCi0+IHBpdi1wMjU2IHBE +YXpSZyBBekVjeDVqSDdtVTVZb29JYkpxTnVWaGdLdGYyenB2OTJGQjVUNGxXc3hq +cApyejR1bUpocVBQOGF5N3cyOEtycGkwdjIxM0tHUVpnWXJObWxXVjR5bVlRCi0+ +IFB0bkAqMS1ncmVhc2UKZk9ST3RnTHlaRmlVWEEKLS0tIEZLaFAyendSeWI5dVQ4 +ZXE5dEdnbzdkZ3FiTyt1QXdEaGxOaWJRQUZNV2sKfeYlywwJPzsS2U8Y6IPh+/k+ +SPOzJiGHn0cXF1iyCM+r//bU0Pw0hE44I1H9IZBrdYwiN9UuYAJLZKaq8PervLl9 +va2wYQGHtTTsSrRA0pprQ+4NbHZI+Bx7Y70PZCLk3nK5Z+yZTVdXVXTKmJTCfiX6 +RZkc6kJJaX14aKsdDdIrjTmavZX1qTdTFYTJGXq3hVOwTdvMELimTLVPZkwAE9Ng +Wt4ZzFqsFEEE1Cfau2wQgtYwHXqtywyMs68MyzZzTP5EWjetkX8SoSLPByTFiya6 +wIcHchM6Er7Dq3zAuCSQeGro+BcxTtsLqpn+UpBYc9Y4e4Q156DKdTtyB1jmBkLe +izDXkt6St7mKdGH3odvpyi1wNuG8yroM7RqVeyF0tA/4s46Z1OPYbL6YbKkX8LM/ +A438QSXY+RtFt1dYvjzIHwh1lfnzE8gCNTWZjMQfiXYGZA/zdLiEus9PFuAsoZtf +X55fGeNP8vPdV95cPt04vO+dXK1cNge8Nq5BUuZVY9ASOAfSVPCicdoE7lvk6bxX +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 -----END AGE ENCRYPTED FILE----- diff --git a/dot_config/encrypted_ytsubscriptions.txt.age b/dot_config/encrypted_ytsubscriptions.txt.age index 4ae6f43851201a3cc02e113936c8d33ddfb7d3ad..cf39165b96c1edab9399683a908f55384cf6d34b 100644 --- a/dot_config/encrypted_ytsubscriptions.txt.age +++ b/dot_config/encrypted_ytsubscriptions.txt.age @@ -1,29 +1,26 @@ -----BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IEhBV2NqUSBBbThZUVRt -bmIzbk1KS0c5K3ZJZlNkcW16dkc4RjlrZG80QkVndlVydk5oOQpYQjZsd0ttMXB5 -WVVGQ1NSTCtyeE5US3ZtVGpzYnQ5MXZyaWxQTGFWS3VVCi0+IHBpdi1wMjU2IHBE -YXpSZyBBbDRJQWlZTm1pRlJLN1N2SEVYc0prYkZUN0RSWkVjbnB0VGxBYU9mK2JX -eApaeS9yWmpoQnFKaFhtQ2dPTjR1S0trQVJjZlhFanRBNUZadWJBUUpMSDUwCi0+ -IFNPMW4tZ3JlYXNlIDEqOickSiEgXCRGXyBVMkZXIH41ZUAkTApOZzlsRk02ZjdK -QitVMXR2SXg2ZWtrcjVxSE5WSHd3M2xyaTdKT0M3dVUvR1NaOEFBN2YwOHpnUFBr -VmFUVG5ECm1IVGpPMWFPd0gweWRWa0xNc3E5K0dxQnRnRUIvU3AwUTVpd0J2dE40 -SzhaRXNWeTRPMWdzby9YSVhRVgotLS0gOUZxb3A5c3ZtWXczbXVkTXRwNGlLYVUv -dCtzMzUycHlRV2lyU2hpcVg5WQogH7jv9knJvy/XUG3/78RGg0DjBAwDhdha5Opl -Wwjs/9qLPFYgKW4kUVW7HqlJ10YrYOaJvquK77a1o1mA1aYE4Qw6vD8NbxATuNNk -Ykrthjhu8wioOrRZtMB1rKAcl1GaBH6S/jsZrp7K6wNXYH3fYx/1AW+QN0INTS4f -CSX0VQwskQunNcUKcmNmyzaeitFkyKeBmPkUddNAleE4ulQ5NLeHsYzNPR3eE9JD -fvWa3KvzMLzxbrvS1pBqFL+cHBPWDiKjFuXMGAxnbSIWd08JAg3vRZ/lWI55/+3z -frRieXSYOvlAw1/UoT1jbMoUYSwhunDDh9OWOT16YM72tlpXRTFfVbh4mxKYWTk0 -MugKGP/QuuaUH56h2hXrBL5+PzAaMigI6G5o9dIHhgPufHnIHLzbmSWSH0V1BGtI -RSHExePHk/VrQkSO9Hft8iNdvJtEJ4eI4qYYwjYOpjkgri8N/daO6dmgY2S3NngH -9eZsTo2dS8jt1HY9B7+jkVpoCYFaX3Eipet0MtnZPqCCi4EzGR+/79FIspJXPvWb -ealEu91VFeqb9WGiPcSk4OZmKicrLx3Dw90Ts4VbR3AW5kxKWyOrFHTwSpZLs6+i -4G3xrqZ85T5ZTvT4m7rZQDeoUq7k8WmBcUUlntWsmjBSvUKq2awTyI/+95rKeKwK -cjHxUCXH1YKDcCkuqaS1NdSjrUXuhvKn8ESxpE/5QIqABr8AKvR3j//rXGqtqC7D -rv7kMHviP0uJqzM15cYZ+BT6fwM04a2nF2wT/WPhk1DLIviYRQzZb5P2W/2nCOP4 -+bmB9PINM0yGc+OqHzelKGRKN/yh390eZiQygb/U43ceTAwXfVdIW0svb1+4dlQm -mjPgQnTRSasOo4hFUK+IbeELB4gTswVpu02mdM4I0KlkK7mvYDxsZzY+OGxxb8Re -k+MbwZ6DbMsfGt2VGGM9LWeaWrnPBhbR5XDhuNj4w/ca+GdiLdloRuD72uCGYed6 -UDP0ANRt6C8MGJqINmCOQceYgkhP8ColktTLk6b0DspmY9mTCBED5EXgD5o/qnlM -ui9VFT75Rr9eELebT2s2IU+s69ESaTPrZ3bNDqSDMkeYbdzfcCsPwI9sz38fow== +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IEhBV2NqUSBBMVJ3aGtZ +Z3dVbmYvZUJudXhja1B1bUlHRGJzdi94N0FtSlNUenJvV3VadQpaOHR5bEpkYjJy +UnI2OGoxWTZEN2FQaVRzU2tpd0g2TlBmRUhIcCtteDZBCi0+IHBpdi1wMjU2IHBE +YXpSZyBBMVl3a25ZRUs4YU9seE5PQW1OWDZyOEh4RXRBZ0t1azZFSEt3T0lLcTQ3 +cAp1WFh4aFV0VG52VTFhM3VXUW41UG9XQnZ5bGUzajdqbGptUVRLdkdlemFnCi0+ +IDxVaW8nLWdyZWFzZSA8fSBAY0EuIDB+ClpEeFlvY1JSWFFoRFhsVGRXTXp6YjFF +SXVlU0xwMzY0N05BCi0tLSBzNHFLbEZXRENpUkRqWTRLQ0N1QlZObFZtZFpmQkcr +TWN1WFRobzZZN0lFCh1kjTRNXk8Xm3hqf5IjFjZ/ThsnLtLZ2U9wR+AQzVggENXI +vkXAbCMAVH3Q+DUjCM0kwhp2+GJOW/U0KjEa/UGrwokZwzhs0M5yAjw4RiwyoOoR +CxewEV36tvW/9ruIfQvqWxPNewknp4dmDo4YqJ5JM6R4EJgywHRqPDgMk+WZ6jXi +ndYdmfo3K0i34DzmYMw8wIlc646V7UIIJYp0n8Ff0AiS78pzFvjlmtE3TdWqeeRX +xNI3iQ6DRXirkiumoVItqU1ykWK3CbXEDQAHeKpGKNCJ/yT2v2Y27TZTJ3yGACNW +dxedoJi1gh/kEUEL+adifIjbZiCFH+my8jVK7plWvav+0+G0cuK1euFNp/ZCPujA +pFevpbwUkPWcNmbxFvAxd+8vO9e+2Msk6BRVNtOWvKoOQa2BXYDqM1qdOv2iV0Me +V0VTDBRbNoyz/CrTyNEi3aYEFUvsHgnPD3XXB9uJFL0+wbLprVn2F0jVaBPublnl +8XHKRL8aJS3q2u1CADXNdOMnYpoHHNFr77qBi2L4wIBWoqfWU5vNYUu8C49NwuxD +dlIqw6yA/OcnQgFs+xKkOq+of9aRC65zHh2rxttsHo7RvjnQALnb3zLOOR56NhQ2 +ZQCkgrAQYGg6G0NtmK7H3N23yM12IqHmlBn8QRZCdb7hMMw/8gLf5RpreJviSqzo +tOtZAxBC4UkZhAhQDBZ7GMzvHHwFQNd4ntXH6C7qiRJaIw+hlUI25yuGE/1k1s0o +PHtEcXeuHqs2Sgdwe9nM9MdvZqpXGcsnuE7Z0xantXlOLWpx/t61IOPoPnhj0vOm +q6ARC6jpFAUJ5v4UEf3Ss2bzbwfWFAekaRX1t4GVhhUHRK+OxO7xs3OsOya2sLzv +kOCMjC6nsOlvkRE4xtMtM9Kdh2foCvPkxecChIVYkRWASDFmjAd+Sqo2rYTEOlF1 +zZttUMEFcLN0PQMfIAnLpn0LtaxwiodmdGtMEHWE3yMVQ98xYmfuoJuKrySDqfq0 +W5lPZjjx0mTUXZH5poRpg6JAr5I46Ag= -----END AGE ENCRYPTED FILE----- diff --git a/dot_config/git/config.tmpl b/dot_config/git/config.tmpl index 370561c20aa0eaf36d86843809c413b2b4f9614e..b23ac3de58893f80ae49d1af7681a39d56b70d12 100644 --- a/dot_config/git/config.tmpl +++ b/dot_config/git/config.tmpl @@ -2,6 +2,7 @@ defaultBranch = main [user] {{- if eq .chezmoi.hostname "angmar" }} + # {{ .chezmoi.hostname }} signingkey = ~/.ssh/yk-stationary.pub {{- else }} signingkey = ~/.ssh/yk-mobile.pub @@ -49,5 +50,3 @@ smudge = git-lfs smudge -- %f process = git-lfs filter-process required = true -[url "git@git.sr.ht:"] - insteadOf = https://git.sr.ht/ diff --git a/dot_config/isync/encrypted_mbsyncrc.age b/dot_config/isync/encrypted_mbsyncrc.age index 671ab79ebb47e091c3a537daa4ac52cece7d0a86..9d25b2850d520241b62295a70879015fd78b33d9 100644 --- a/dot_config/isync/encrypted_mbsyncrc.age +++ b/dot_config/isync/encrypted_mbsyncrc.age @@ -1,45 +1,47 @@ -----BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IEhBV2NqUSBBeXlITDNv -RzFWZ1JiOVdKdXhleGFrbWU0ek9QaGVWdmptWDNTckJVTDNoTwpiUzcvSVpXYUg5 -OXJOdGVybnp4TXdzQTNVL1NnT3ZTSXBVektUOHdFbnBVCi0+IHBpdi1wMjU2IHBE -YXpSZyBBc0o3TnpKajM2M1d4NEhBUGtYV2NHZlVUdDhZWDUzL05TR2p5c3JDWWMz -LwpiOXBaWnV0a2Jmb0R2RSswSU1odHBmTUlTMlB2Q05oOHJ1dTQ1S0xUVTJZCi0t -LSBYNGx0cnBJTmk2WGdTdERORVBoRDdxQ2RyT0VjZGVuck9KdGoyNU40OThvCutv -MD+I/sNKpbSV4mNu8Q/rCRIrbYaibtdkaBk6uUo69dSChRzSaYnUbg9PB5VSw144 -nFRRydOKpiQC9PD/mL7UV9E0XIpgLEehlrYYKftWBUv7DuLFJgF74UOgzhy9xDAK -OsGsAnU4itfuRRXGMnNv1reL6oGZLtxFb5uNCLuO6PoBjf2HrMMUQy2CccyUWEaA -iLcnOpwELYRczHlFIgmu9ywOU83VV/h/XP0tcwHWkp+tCBMkBUBn2YccpH/y7FrI -1pBb5oqGLGK0lBrEcaf49ylCTRHTKSXvHSWRdXjj/9ZLTayAUzXa4KZXEFf+YAFZ -Jx9Fc5cDAp1nl9qOnwaqVLIdGHVtCIAdDZ9q/BaOMzmITfXzwWOF+m90dN1N2Dtm -fWFWgun+RTZ0NzHM9vx5YhsatmPZ+zqOxTwwhbPcTdztvoeDk9O/U8vom3HlJcV3 -2H62LVkUmkIsyIdbNXOP9agy7tZNsJ/6tTvsgMqfbV0MiTChOTRWDMZ+AkR5r08v -hF+ZvjlRJHaB7yYsQLQmXdSFE9R7eg3DekkLMdGfbxt53UZWe14QxrhEqRR+x1J3 -KupS1/+DNC9Gy2ISC9sSwK3/iNfkNCD8bRcOJX6+pZOJrX5rnGBa/ab3TCMw7waZ -4WDefTgOl4bz5kwtfj2qLFhWvXjCY3xJI0AmF6/6qwmIdQtHDWp5gtHTtuuJaIuO -oWoJLRHRULCVsaKvxyh3eO7yyBy/VBzCWBjpyc/ldxKzlsDPjqyJn3xRfd+vFrC8 -pn094vDoAa0LXHBr5z689NE1iNR6Q6X+6QXdZfA9r1L4OmZXZ7jX7w54UkcPVy0P -9TPACvYZ3LCECHcPmCnivzZ0JrPlgsbxNLdo1tV1VwdyyllFQdOIoI7a/f8FOAYY -ZdlGgLiw1iUqgPC4RwU5iRXIq0ezQLg22TFr3XUJx0JNp2mbhxCACHNKfHPJIENc -TzDCPFfY5B4fRqh/nt5Jxz8O7M1GMstyJvG6rJlEO9/+AvL63bKAZdeM7rUlHcME -q57vIatTKQfPopzgGFMZweIuZKHd++qfayPmGZ+T/ffxohqunFc5tQ4qhkG55TTd -63/v7jUruPWS/E8TjMre4y0qi+lOKEGjEtdUjdOFlIhNw3JwJp0rKeZDC7zwQ6Mk -z1TRnJPIqTwhJY3TIGmGVFVVT4iCCTLO3svFsZCJAbb30GsHudQwcYKDx1oUDi+A -uDj8+199MoAVG7KmlbY8F5LtEoQPNXYmhUkwKWe4HBpM43nE2RDZ50mPLmNFJgoI -9VPhprN75hRiOzPoCYHBnJlIpKWmoX6mx9lpg0GMhdIcs24vGTwy2DngW4IyEuuW -Hp0RRvc7ZsZotAjz4dHmOo2O95lwPilmA5sgGj1ESEFzbDR9GibzKJzHD+vq4Jw3 -1ImoV3rASY1YfKXmGvpCPQt69HPMQlTErMEdmxGZIZ6577Bsva7oFQxt7Y0Kd9to -M4N3S3ITPCxMtSYyY5n/80YtT/lcb1ltS2k7tNRAUaaDmQkbpqQlWPL7TjQZlCXz -ti1IhtJavCG9ER69G3pKkgAY1gO2lyntnmHMooj0SbHza/5g8WTqL+rbQNyxOBok -OX4PMvnT9E6/k2gpTkeRuCI3E1DWywKEB/RA0jHIZcU3WC05Qh2Yx8F3DLTW/hBn -ooChNyagg8JgLBisK14TQy6qCL54DaEHM3ZPzo2bnibfXV3MABZ36hfm5j2q3g90 -UFvS4scOxMdVTob+DjFXQand88jR9ldmDZP9kXr2P/PEG96ghVmQ06HOy7e4CCrk -xAMIjfGb4BjzbvpIODrBRW6JfK1YgSWZw3+zEZqYtxZvBQpZ4Q2Mif/nmpVVVovZ -XmEgBVQIYWDzINbfDvdgTBquxRh43VclBZ7V6AbJsd5VWPMMLADHJj/s+ynsSsT1 -7i7tLJ2w0jlo3g6iFDs095z1qY+Ek0qCOc/pRIsQLG5sNs/gaT9NQ/hbIUV0hNlE -Hb9yQeorEEGf9NwOmPLEtBQrKXqLteV2OpUQdGg22uyjv+adBNUQuVCG99cxBexO -ucgvjdNtuahWYbzLOA6d6h3hKi0Nj9QRxJ88wp9bJFXsUGg8TCbGDsL8DMmtijL6 -ooRHl1qZN9TZhxFzKpx3nE7AAeyyiV5V0pRpMfNbNf9JMCVZTMcVW3yFK1pQCIY3 -QovAj/0gdb7KEJK8blub8EopvY8goSsFon0kxmmsssuml+vbypBkWlc+2eYqYZ6W -Es7jCTwSmmdxIld1naR2Ti3115namC6SOBfqUPHrJcsSPtyWHYg8R8IOpioWnn5S -h14l05vIg5zE8m3zl8Yzlp0ARJA1FHum+/l+Q1b8W9IG8Z9mgyjUjsJONVTzlB2X +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IEhBV2NqUSBBdk5Za1JU +VTJnUzE2Mk1QZW5ZdkZUU0QvVTFDTXRSM1pWNjNnWWlCY3ozMQo0a1lFa0xFVHBk +MHp2QnByVUphalNCc0M2emtLSldHZUFwVFRFRGZ6dHpZCi0+IHBpdi1wMjU2IHBE +YXpSZyBBeUNXcVlwTm56blFPc2hETy9SdnB4WHptcFFvSTlvc01rUmJGZ3dGQVZZ +NAorVzRKcTZSdmtXR3kvRHBuSnlSUE8xcUsrR0lsKy9KV1ptNmZETUdVaUtVCi0+ +ID00Pi1ncmVhc2Ugay5fRj8nIElWN3dkRyA9TS1rVwpzYzQxKzkrdTZ2UXIrVDIw +ZmdIbnU2Y1ZxaTdwUlIwZXRkYUw1bUJVdkovUkUyYwotLS0gWGZYd29qb3Q3SGFE +WDJWNjNsb2Y1cXlZemsxMkhCcXQxc1JkaUNqcVdiSQohDWKEZ7K2JBAC8g9ekSlN +DeNIbSnEGKEAfQpIi9sh23MuKbKM26zzK9KXqPm7uPwJ7RrstFiyybRYlLvBMgL/ +VOLV7pu3Poyt+UTpg2plmOFiaHSe96yZBauDzZDFTsuqJUysHyXzOyk6hC34k8zT +luqBuZYlkQ0LJK/pF63nxU58ZaJAE6F3gWMjhdtwUKN7Uyt//wEfoZR/c2Dh9gYn +hNc8EIIQxtdoCvLTobJ9uBY5AinDLLElbi9E+16HwitumhvC6DHatOJdFNFlCo3P +hpexmj2iyRzx0v2WRo5rn4/IBljGoWL/8MZSz4g/SSfuBqb6uqy6lh99gSKD8Xnn +4BX8Ne9lvMsHjHDCh5a9d6SZJR1G5XseK+S28DPtegZCG/AdoN36eNKyo13/6kFf +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 -----END AGE ENCRYPTED FILE----- diff --git a/dot_config/msmtp/encrypted_config.age b/dot_config/msmtp/encrypted_config.age index 0ba7bdb4c06f8d01b1c95108634933fe1f42471c..7a7e2bfa19b6c14b9da102582e114bb34e25fd3f 100644 --- a/dot_config/msmtp/encrypted_config.age +++ b/dot_config/msmtp/encrypted_config.age @@ -1,58 +1,64 @@ -----BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IEhBV2NqUSBBdjVETGd1 -czA0TE1ISFdXRjRQY05uVVJTUVJhSzRSaHFqMWo0SUxwOUtTcwoyVFlvUGdkc2Ja -YmRPcWtPb2JrRXRXRTVySThPaE9aSUpZOEMxTGVyNEdrCi0+IHBpdi1wMjU2IHBE -YXpSZyBBc1pQQ1duek5RSHhZNTdxNWJVVTVMWTJSMGhpTGs3U3VUR04zR01MMWl4 -WApDa2o0aDlLYUQ3UTNiSlpqKzZPckJHUkkwYS9EcEw4a2hMTXZQTnNEVXpvCi0t -LSBLRy9TbWdVd2ZyZnluSE8wRXFjaTE0TTdaeFJhRUIwRjMzR3RLRHRxNHdJCosk -DjcVFTCpdzOmwL2vFZlBCplLt6YBVI8ELxMKydRCIhoM9aHbqjZ02ppIN2dYu1Fv -vi3JYsrp9rSkesd+RSdIdxlLaDF6OKwcl+v/K7BisxUuNtdDDBIRB7ZCJxyDOd4z -SEwh8PWKxu4mLOVULiY9CLEyzp3/hVPCQKcqFfswHjeNyx3LYf3ubGyioRmFhTKF -s4+ccznvqiNrHlQrBxq6y2P/rhBjOVng2vq38odkSUi5sBZnlVQglEAoRSrokDrs -T85voWFS44xQ+vG4VABVYJXLyNqsQ2PuH0U52ctcN6iJTkMBdz+YGvRagWKQTNCz -P7kAj1xDRIejUtyKUD5Wps0R8j9mgbnLRvhUk8uox461EYJ/MVyF/26BOlZYXeSW -w5U8dGgOscGl+DkHRPOHike+qkuer7JJRXp/ADurvRZhXJJ7AtLtE98vQpEwVGtv -uthTMy6du1JWffl7UMxCQ7FLwgojMGLoFqN/1H74/DKuPTMESvV1D8XTUYoyxy4G -vaC8ZXAAd8nshxLZweMRltiQj67wgEL3RYPHB/TL5DDtP2rRjiCZbdaHiYdVjJgH -bzRPXlCkXPBgqW6Ehass/4I7lW/7aGwcMTYBNJaI8wDKnxPOiZ+40eV9Z35AVIIo -MT7AMT6AaQ0zQTBZCOT9L1exzEwLMMsEmZ9GisUkHsOsqghSmQ57eRsW+deRPbHD -PDCR/p2R/37tp0CLobnpyjiIR6ooJU+7nSI/T+vwInHUObqjjbMaNnWbQexgRv6z -K3VQoznGIXNEnc1pQybTgDtQ61UH6jE6AlelO9/VVoK7dFAlHfyYD5FOpFcgAn2G -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 +dXpYSUJla3NId3hjQmtPTG5GcHE2dzU3aGNpY2RobW9IK0Q3cwo4bHNEd1loUkc3 +QUZ0ejd4bW9CLzFCRmpSY0Q5Tk5MN1lWS3NNVXB1TUY4Ci0+IHBpdi1wMjU2IHBE +YXpSZyBBaG1wSE1rMEZtTEQ2WXFHMFNQL2JSZFhtelV5WHU4UWgzTGZyR3E4SEor +SQpCU3pwUWVkRGs5SXZUbFU5eUM4cS9aSDhzV2JncUJsd25VY1dXZTNlR29rCi0+ +IG0tZ3JlYXNlICJcIGhBM1xfICpWLDM2R0JKICkKQTNWd2R6ODdLRFM1QmE0WEEw +eUVYSDJTSi9oWVd4Umo0OERFbDRObkUzbHd4cGtxQkxsZVAzdFdEazBQbUlMOQo2 +dWUrcm1PcGl3Yy9HRGdybFI2SXBVc1QKLS0tIDNGM3I4VlNyR1J5MnhlenM5Y2I3 +WUNHSGZxOWZMcWtBUFhYZTJWUTJTUjAKuyf4O6+aRarG1AqEO2H+lVnAv1p5YXfj +wL1ROgwqY/0pl0JONI/5bZKqx0odo/seDMpKENVBDZjU69riCVPRE4WJxRK77yk7 +zvBiR1A4i934JV231icsW8WzCvYs3n1e3kKWkF75ictXiV0rLYE27+HQJHwGf0ns +rcyofuBVrkkhcscw77QYYJJkxvRuf7Xbcr24oacG7WIYgYvo+TDqqxxm6WmxVaib ++9YR/box73wM5H9Niof9tmjZE6RQEOSoUNs50wJL0hHxGNlK/7pm4KsrQdDcZGw6 +CjRsTyYxHwi3tlPltlyvsEQPQZRpsbLvCoDCioJl1lU8FvcozwMwVB0uJLTxJx41 +Q8I2RHL32y/Y45jevJURJlf1SKN5gIpljUZUPK6KN6Ta9Jvc+wl4DGbJOYiDqMzL +9u/S483LyFWNrX/etAqlwr5riztuZAITOKUH4P/BYrGN8DA8sfBenDPuUVjlY1pd +9N2+VA/4uBJjDirRqy0988lHUog480P9ZZsAq0E9J3wViWWNnO4yv0FceC8dFZN9 +2BkExlcLwx/JlqdrX1JwZVzeURsIlsCBmOV6p3Dga1+hwPnMDVnuo8lOg+HqpfqQ +AIctVHdXsCyZ/91C/+pSQ3dLK6PW2FX9zIgs1z91+Mc6QpJX6jqao5NVZvNttB5v +Y+VqO4aFTElMi7RC0gxzcVmuHq+2ZJQsiSzj6WTH1e9Zz6JJhbQ1iMPP21O14quq +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 -----END AGE ENCRYPTED FILE----- diff --git a/dot_config/nvim/init.lua b/dot_config/nvim/init.lua new file mode 100644 index 0000000000000000000000000000000000000000..e8249707b140949ad1cd6196ddf8ffb6a5fd96d8 --- /dev/null +++ b/dot_config/nvim/init.lua @@ -0,0 +1,27 @@ +-- HELLO, welcome to NormalNvim! +-- --------------------------------------- +-- This is the entry point of your config. +-- --------------------------------------- + +-- LOAD SOURCE FILES BY ORDER: +vim.loader.enable() +for _, source in ipairs { + "base.1-options", + "base.2-lazy", + "base.3-autocmds", + "base.4-mappings", +} do + local status_ok, error = pcall(require, source) + if not status_ok then vim.api.nvim_err_writeln("Failed to load " .. source .. "\n\n" .. error) end +end + +-- ONCE ALL SOURCE FILES HAVE LOADED: +-- Load the color scheme defined in ./lua/1-options.lua +if base.default_colorscheme then + if not pcall(vim.cmd.colorscheme, base.default_colorscheme) then + require("base.utils").notify( + "Error setting up colorscheme: " .. base.default_colorscheme, + vim.log.levels.ERROR + ) + end +end diff --git a/dot_config/nvim/init.vim.tmpl b/dot_config/nvim/init.vim.tmpl deleted file mode 100644 index 1f1681fb7a628c9fe3bdcca482d8cc959fd5e1a8..0000000000000000000000000000000000000000 --- a/dot_config/nvim/init.vim.tmpl +++ /dev/null @@ -1,142 +0,0 @@ -let mapleader ="," - -if ! filereadable(expand('~/.config/nvim/autoload/plug.vim')) - echo "Downloading junegunn/vim-plug to manage plugins..." - silent !mkdir -p ~/.config/nvim/autoload/ - silent !curl "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim" > ~/.config/nvim/autoload/plug.vim -endif - -call plug#begin() -Plug 'ap/vim-css-color' " highlight css colour codes with that color -Plug 'tpope/vim-surround' " highlight open/close characters like [], {}, () -Plug 'wakatime/vim-wakatime' " Aggregate editor stats and metrics -Plug 'catppuccin/vim', { 'as': 'catppuccin' } -Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'} -Plug 'github/copilot.vim' -call plug#end() - -{{- if eq .theme_variant "dark"}} -colorscheme catppuccin_macchiato -{{- end }} -{{- if eq .theme_variant "light"}} -colorscheme catppuccin_latte -{{- end }} - -" LaTeX config -let g:livepreview_previewer = 'zathura' -let g:livepreview_use_biber = 1 - -" Grammorous config -let g:grammarous#languagetool_cmd = 'java -cp ~/languagetool/languagetool-server.jar org.languagetool.server.HTTPServer --port 8081 --allow-origin "*"' -syntax enable - -"" -" Some basics -"" -" Make ctags for supported languages -command! MakeTags !ctags -R . -" Add all subdirs to working path so :find works well -set path+=** -" Status line completion menu -set wildmenu -" Set above menu to a vertical instead of horizontal list -set wildmode=full,list,full -" Wrap long lines that continue past the viewport -set linebreak -" Highlight the column the cursor is on -set cursorcolumn -" Highlight the line the cursor is on -set cursorline -" Enables more colors -set termguicolors -" If there are folds, close some of them on startup -set foldlevelstart=99 -" Use system clipboard for all yanking/pasting -set clipboard+=unnamedplus -" Use tabs but display them as 4 spaces instead of 8 -set ts=4 sts=4 sw=4 expandtab -" Round the indent to a multiple of sw -set shiftround -" Set hidden character characters -set listchars=tab:▸\ ,eol:¬,nbsp:␣,trail:•,space:.,extends:→,precedes:← -set backspace=indent,eol,start -" Keep 12 lines above and below the cursor when scrolling -set scrolloff=12 -" Disable mouse support -set mouse= -" Use indents to determine folds -set foldmethod=indent -" Set line numbers relative to current line -set number nu -" Show partial commands in the bottom right -set showcmd -" Show which mode you're in -set showmode -" Display partial matches when searching -set incsearch -" Highlight search results—hide with :noh -set hlsearch -" Wrap searches around the end of the file -set wrapscan -" Tell Vim to be more liberal with creating hidden buffers -set hidden -" Case-insensitive search unless term contains uppercase chars -set smartcase - -" Statusbar theme -let g:airline_powerline_fonts = 1 -let g:airline_theme='bubblegum' -if !exists('g:airline_symbols') - let g:airline_symbols = {} -endif - -"" -" Keybindings -"" -" Insert timestamp at the end of the line in this format: 20200527T113245 -nnoremap m'A=strftime('%Y%m%dT%H%M%S') -" Open a new tab -nnoremap t :tabnew -" Toggle hidden characters -nnoremap :set list! - -" Window management -map h -map j -map k -map l - -" only enable persistent undo if vim supports -if has('persistent_undo') - set undodir=$HOME/.config/nvim/undofile - set undofile -endif - -" Only enable autocommands when Vim supports them -if has("autocmd") - " Disables automatic commenting on newline: - autocmd FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o - - "" - " File-specific indentation settings - "" - autocmd FileType make setlocal ts=8 sts=8 sw=8 noexpandtab - autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab - - "" - " Markdown Configuration - "" - " Treat all .md files as markdown - autocmd BufNewFile,BufRead *.md set filetype=markdown - " Spellcheck in British English - autocmd FileType markdown setlocal spell spelllang=en_gb - - "" - " Working with LaTeX - "" - " Reduce udpatetime for faster previews - autocmd BufNewFile,BufRead *.tex setfiletype tex - autocmd FileType tex set ut=250 - autocmd FileType tex set colorcolumn=72 - -endif diff --git a/dot_config/nvim/lua/base/1-options.lua b/dot_config/nvim/lua/base/1-options.lua new file mode 100644 index 0000000000000000000000000000000000000000..fa6a9b574ebe2a690d16285114ad2b11df8a32ab --- /dev/null +++ b/dot_config/nvim/lua/base/1-options.lua @@ -0,0 +1,93 @@ +-- HELLO, welcome to NormalNvim! +-- ---------------------------------------- +-- Here you can define your nvim variables. +-- ---------------------------------------- + +-- NormalNvin lua globals +_G.base = {} + +-- Theme +base.default_colorscheme = "tokyonight-night" + +-- Options -------------------------------------------------------------------- +vim.opt.breakindent = true -- Wrap indent to match line start. +vim.opt.clipboard = "unnamedplus" -- Connection to the system clipboard. +vim.opt.cmdheight = 0 -- Hide command line unless needed. +vim.opt.completeopt = { "menu", "menuone", "noselect" } -- Options for insert mode completion. +vim.opt.copyindent = true -- Copy the previous indentation on autoindenting. +vim.opt.cursorline = true -- Highlight the text line of the cursor. +vim.opt.expandtab = true -- Enable the use of space in tab. +vim.opt.fileencoding = "utf-8" -- File content encoding for the buffer. +vim.opt.fillchars = { eob = " " } -- Disable `~` on nonexistent lines. +vim.opt.foldenable = true -- Enable fold for nvim-ufo. +vim.opt.foldlevel = 99 -- set highest foldlevel for nvim-ufo. +vim.opt.foldlevelstart = 99 -- Start with all code unfolded. +vim.opt.foldcolumn = "1" -- Show foldcolumn in nvim 0.9+. +vim.opt.ignorecase = true -- Case insensitive searching. +vim.opt.infercase = true -- Infer cases in keyword completion. + +vim.opt.laststatus = 3 -- Global statusline. +vim.opt.linebreak = true -- Wrap lines at 'breakat'. +vim.opt.number = true -- Show numberline. +vim.opt.preserveindent = true -- Preserve indent structure as much as possible. +vim.opt.pumheight = 10 -- Height of the pop up menu. +vim.opt.relativenumber = false -- Show relative numberline. +vim.opt.shiftwidth = 2 -- Number of space inserted for indentation. +vim.opt.showmode = false -- Disable showing modes in command line. +vim.opt.showtabline = 2 -- always display tabline. +vim.opt.signcolumn = "yes" -- Always show the sign column. +vim.opt.smartcase = true -- Case sensitivie searching. +vim.opt.smartindent = false -- Smarter autoindentation. +vim.opt.splitbelow = true -- Splitting a new window below the current one. +vim.opt.splitright = true -- Splitting a new window at the right of the current one. +vim.opt.tabstop = 2 -- Number of space in a tab. + +vim.opt.termguicolors = true -- Enable 24-bit RGB color in the TUI. +vim.opt.timeoutlen = 500 -- Shorten key timeout length a little bit for which-key. +vim.opt.undofile = true -- Enable persistent undo between session and reboots. +vim.opt.updatetime = 300 -- Length of time to wait before triggering the plugin. +vim.opt.virtualedit = "block" -- Allow going past end of line in visual block mode. +vim.opt.writebackup = false -- Disable making a backup before overwriting a file. +vim.opt.shada = "!,'1000,<50,s10,h" -- Remember the last 1000 opened files +vim.opt.history = 1000 -- Number of commands to remember in a history table (per buffer). +vim.opt.swapfile = false -- Ask what state to recover when opening a file that was not saved. +vim.opt.wrap = true -- Disable wrapping of lines longer than the width of window. +vim.opt.colorcolumn = "80" -- PEP8 like character limit vertical bar. +vim.opt.mousescroll = "ver:1,hor:0" -- Disables hozirontal scroll in neovim. +vim.opt.guicursor = "n:blinkon200,i-ci-ve:ver25" -- Enable cursor blink. +vim.opt.autochdir = true -- Use current file dir as working dir (See project.nvim). +vim.opt.scrolloff = 1000 -- Number of lines to leave before/after the cursor when scrolling. Setting a high value keep the cursor centered. +vim.opt.sidescrolloff = 8 -- Same but for side scrolling. +vim.opt.selection = "old" -- Don't select the newline symbol when using on visual mode. + +vim.opt.viewoptions:remove "curdir" -- Disable saving current directory with views. +vim.opt.shortmess:append { s = true, I = true } -- Disable startup message. +vim.opt.backspace:append { "nostop" } -- Don't stop backspace at insert. +vim.opt.diffopt:append { "algorithm:histogram", "linematch:60" } -- Enable linematch diff algorithm + +local is_android = vim.fn.isdirectory('/data') == 1 +if is_android then vim.opt.mouse = "v" else vim.opt.mouse = "a" end -- Enable scroll for android + +-- Globals -------------------------------------------------------------------- +vim.g.mapleader = " " -- Set leader key. +vim.g.maplocalleader = "," -- Set default local leader key. +vim.g.big_file = { size = 1024 * 100, lines = 10000 } -- For files bigger than this, disable 'treesitter' (+100kb). + +-- The next globals are toggleable with +vim.g.autoformat_enabled = false -- Enable auto formatting at start. +vim.g.autopairs_enabled = false -- Enable autopairs at start. +vim.g.cmp_enabled = true -- Enable completion at start. +vim.g.codeactions_enabled = true -- Enable displaying 💡 where code actions can be used. +vim.g.codelens_enabled = true -- Enable automatic codelens refreshing for lsp that support it. +vim.g.diagnostics_mode = 3 -- Set code linting (0=off, 1=only show in status line, 2=virtual text off, 3=all on). +vim.g.icons_enabled = true -- Enable icons in the UI (disable if no nerd font is available). +vim.g.inlay_hints_enabled = false -- Enable always show function parameter names. +vim.g.lsp_round_borders_enabled = true -- Enable round borders for lsp hover and signatureHelp. +vim.g.lsp_signature_enabled = true -- Enable automatically showing lsp help as you write function parameters. +vim.g.notifications_enabled = true -- Enable notifications. +vim.g.semantic_tokens_enabled = true -- Enable lsp semantic tokens at start. +vim.g.url_effect_enabled = true -- Highlight URLs with an underline effect. + + + + diff --git a/dot_config/nvim/lua/base/2-lazy.lua b/dot_config/nvim/lua/base/2-lazy.lua new file mode 100644 index 0000000000000000000000000000000000000000..e07b2d7edd4ea966107504d40aab9e8c5379520b --- /dev/null +++ b/dot_config/nvim/lua/base/2-lazy.lua @@ -0,0 +1,75 @@ +-- Lazy.nvim config file. + +-- DESCRIPTION: +-- Use this file to configure the way you get updates. + +-- Sections: +-- -> lazy updater options → choose your lazy updates channel here. +-- -> extra behaviors → extra stuff we add to lazy for better UX. +-- -> assign spec → if channel==stable, uses lazy_snatshot.lua +-- -> setup using spec → actual setup. + + +-- lazy updater options +-- Use the same values you have in the plugin `distroupdate.nvim` +local updater = { + channel = "stable", -- 'nightly', or 'stable' + snapshot_module = "lazy_snapshot" -- snapshot file name without extension. +} + +-- lazyload extra behavior +-- * If plugins need to be installed → auto launch lazy at startup. +-- * When lazy finishes installing plugins → check for mason updates too. +-- (but not when updating them) +-- * Then show notifications and stuff. +local lazypath = vim.fn.stdpath "data" .. "/lazy/lazy.nvim" +if not vim.uv.fs_stat(lazypath) then + local output = vim.fn.system { + "git", + "clone", + "--filter=blob:none", + "--branch=stable", + "https://github.com/folke/lazy.nvim.git", + lazypath, + } + if vim.api.nvim_get_vvar "shell_error" ~= 0 then + vim.api.nvim_err_writeln("Error cloning lazy.nvim repository...\n\n" .. output) + end + local oldcmdheight = vim.opt.cmdheight:get() + vim.opt.cmdheight = 1 + vim.notify "Please wait while plugins are installed..." + vim.api.nvim_create_autocmd("User", { + desc = "Load Mason and Treesitter after Lazy installs plugins", + once = true, + pattern = "LazyInstall", + callback = function() + vim.cmd.bw() + vim.opt.cmdheight = oldcmdheight + vim.tbl_map(function(module) pcall(require, module) end, { "nvim-treesitter", "mason" }) + -- Note: This event will also trigger a Mason update in distroupdate.nvim + end, + }) +end +vim.opt.rtp:prepend(lazypath) + +-- assign spec (if pin_plugins is true, load ./lua/lazy_snapshot.lua). +local pin_plugins = updater.channel == "stable" +local spec = pin_plugins and { { import = updater.snapshot_module } } or {} +vim.list_extend(spec, { { import = "plugins" } }) + +-- Require lazy and pass the spec. +require("lazy").setup({ + spec = spec, + defaults = { lazy = true }, + performance = { + rtp = { -- Use deflate to download faster from the plugin repos. + disabled_plugins = { + "tohtml", "gzip", "zipPlugin", "netrwPlugin", "tarPlugin" + }, + }, + }, + -- Enable luarocks if installed. + rocks = { enabled = vim.fn.executable("luarocks") == 1 }, + -- We don't use this, so create it in a disposable place. + lockfile = vim.fn.stdpath("cache") .. "/lazy-lock.json", +}) diff --git a/dot_config/nvim/lua/base/3-autocmds.lua b/dot_config/nvim/lua/base/3-autocmds.lua new file mode 100644 index 0000000000000000000000000000000000000000..937ed7273505c438821a1795a3b4ab53f2e2248c --- /dev/null +++ b/dot_config/nvim/lua/base/3-autocmds.lua @@ -0,0 +1,281 @@ +-- General usage autocmds. + +-- DESCRIPTION: +-- All autocmds are defined here. + +-- Sections: +-- ## EXTRA LOGIC +-- -> 1. Events to load plugins faster. +-- -> 2. Save/restore window layout when possible. +-- -> 3. Launch alpha greeter on startup. +-- -> 4. Update neotree when closing the git client. +-- -> 5. Create parent directories when saving a file. +-- +-- ## COOL HACKS +-- -> 6. Effect: URL underline. +-- -> 7. Customize right click contextual menu. +-- -> 8. Unlist quickfix buffers if the filetype changes. +-- -> 9. Close all notifications on BufWritePre. +-- +-- ## COMMANDS +-- -> 10. Neotest commands. +-- -> Extra commands. + +local autocmd = vim.api.nvim_create_autocmd +local cmd = vim.api.nvim_create_user_command +local utils = require("base.utils") +local is_available = utils.is_available + +-- ## EXTRA LOGIC ----------------------------------------------------------- +-- 1. Events to load plugins faster → 'BaseFile'/'BaseGitFile'/'BaseDefered': +-- this is pretty much the same thing as the event 'BufEnter', +-- but without increasing the startup time displayed in the greeter. +autocmd({ "BufReadPost", "BufNewFile", "BufWritePost" }, { + desc = "Nvim user events for file detection (BaseFile and BaseGitFile)", + callback = function(args) + local empty_buffer = vim.fn.resolve(vim.fn.expand "%") == "" + local greeter = vim.api.nvim_get_option_value("filetype", { buf = args.buf }) == "alpha" + local git_repo = utils.run_cmd( + { "git", "-C", vim.fn.fnamemodify(vim.fn.resolve(vim.fn.expand "%"), ":p:h"), "rev-parse" }, false) + + -- For any file exept empty buffer, or the greeter (alpha) + if not (empty_buffer or greeter) then + utils.trigger_event("User BaseFile") + + -- Is the buffer part of a git repo? + if git_repo then + utils.trigger_event("User BaseGitFile") + end + end + end, +}) +autocmd({ "VimEnter" }, { + desc = "Nvim user event that trigger a few ms after nvim starts", + callback = function() + -- If nvim is opened passing a filename, trigger the event inmediatelly. + if #vim.fn.argv() >= 1 then + -- In order to avoid visual glitches. + utils.trigger_event("User BaseDefered", true) + utils.trigger_event("BufEnter", true) -- also, initialize tabline_buffers. + else -- Wait some ms before triggering the event. + vim.defer_fn(function() + utils.trigger_event("User BaseDefered") + end, 70) + end + end, +}) + +-- 2. Save/restore window layout when possible. +autocmd({ "BufWinLeave", "BufWritePost", "WinLeave" }, { + desc = "Save view with mkview for real files", + callback = function(args) + if vim.b[args.buf].view_activated then + vim.cmd.mkview { mods = { emsg_silent = true } } + end + end, +}) +autocmd("BufWinEnter", { + desc = "Try to load file view if available and enable view saving for real files", + callback = function(args) + if not vim.b[args.buf].view_activated then + local filetype = + vim.api.nvim_get_option_value("filetype", { buf = args.buf }) + local buftype = + vim.api.nvim_get_option_value("buftype", { buf = args.buf }) + local ignore_filetypes = { "gitcommit", "gitrebase", "svg", "hgcommit" } + if + buftype == "" + and filetype + and filetype ~= "" + and not vim.tbl_contains(ignore_filetypes, filetype) + then + vim.b[args.buf].view_activated = true + vim.cmd.loadview { mods = { emsg_silent = true } } + end + end + end, +}) + +-- 3. Launch alpha greeter on startup +if is_available "alpha-nvim" then + autocmd({ "User", "BufEnter" }, { + desc = "Disable status and tablines for alpha", + callback = function(args) + local is_filetype_alpha = vim.api.nvim_get_option_value( + "filetype", { buf = 0 }) == "alpha" + local is_empty_file = vim.api.nvim_get_option_value( + "buftype", { buf = 0 }) == "nofile" + if ((args.event == "User" and args.file == "AlphaReady") or + (args.event == "BufEnter" and is_filetype_alpha)) and + not vim.g.before_alpha + then + vim.g.before_alpha = { + showtabline = vim.opt.showtabline:get(), + laststatus = vim.opt.laststatus:get() + } + vim.opt.showtabline, vim.opt.laststatus = 0, 0 + elseif + vim.g.before_alpha + and args.event == "BufEnter" + and not is_empty_file + then + vim.opt.laststatus = vim.g.before_alpha.laststatus + vim.opt.showtabline = vim.g.before_alpha.showtabline + vim.g.before_alpha = nil + end + end, + }) + autocmd("VimEnter", { + desc = "Start Alpha only when nvim is opened with no arguments", + callback = function() + -- Precalculate conditions. + local lines = vim.api.nvim_buf_get_lines(0, 0, 2, false) + local buf_not_empty = vim.fn.argc() > 0 + or #lines > 1 + or (#lines == 1 and lines[1]:len() > 0) + local buflist_not_empty = #vim.tbl_filter( + function(bufnr) return vim.bo[bufnr].buflisted end, + vim.api.nvim_list_bufs() + ) > 1 + local buf_not_modifiable = not vim.o.modifiable + + -- Return instead of opening alpha if any of these conditions occur. + if buf_not_modifiable or buf_not_empty or buflist_not_empty then + return + end + for _, arg in pairs(vim.v.argv) do + if arg == "-b" + or arg == "-c" + or vim.startswith(arg, "+") + or arg == "-S" + then + return + end + end + + -- All good? Show alpha. + require("alpha").start(true, require("alpha").default_config) + vim.schedule(function() vim.cmd.doautocmd "FileType" end) + end, + }) +end + +-- 4. Update neotree when closin the git client. +if is_available "neo-tree.nvim" then + autocmd("TermClose", { + pattern = { "*lazygit", "*gitui" }, + desc = "Refresh Neo-Tree git when closing lazygit/gitui", + callback = function() + local manager_avail, manager = pcall(require, "neo-tree.sources.manager") + if manager_avail then + for _, source in ipairs { + "filesystem", + "git_status", + "document_symbols", + } do + local module = "neo-tree.sources." .. source + if package.loaded[module] then + manager.refresh(require(module).name) + end + end + end + end, + }) +end + +-- 5. Create parent directories when saving a file. +autocmd("BufWritePre", { + desc = "Automatically create parent directories if they don't exist when saving a file", + callback = function(args) + local buf_is_valid_and_listed = vim.api.nvim_buf_is_valid(args.buf) + and vim.bo[args.buf].buflisted + + if buf_is_valid_and_listed then + vim.fn.mkdir(vim.fn.fnamemodify( + vim.loop.fs_realpath(args.match) or args.match, ":p:h"), "p") + end + end, +}) + +-- ## COOL HACKS ------------------------------------------------------------ +-- 6. Effect: URL underline. +vim.api.nvim_set_hl(0, 'HighlightURL', { underline = true }) +autocmd({ "VimEnter", "FileType", "BufEnter", "WinEnter" }, { + desc = "URL Highlighting", + callback = function() utils.set_url_effect() end, +}) + +-- 7. Customize right click contextual menu. +autocmd("VimEnter", { + desc = "Disable right contextual menu warning message", + callback = function() + -- Disable right click message + vim.api.nvim_command [[aunmenu PopUp.How-to\ disable\ mouse]] + -- vim.api.nvim_command [[aunmenu PopUp.-1-]] -- You can remode a separator like this. + vim.api.nvim_command [[menu PopUp.Toggle\ \Breakpoint :lua require('dap').toggle_breakpoint()]] + vim.api.nvim_command [[menu PopUp.-2- ]] + vim.api.nvim_command [[menu PopUp.Start\ \Compiler :CompilerOpen]] + vim.api.nvim_command [[menu PopUp.Start\ \Debugger :DapContinue]] + vim.api.nvim_command [[menu PopUp.Run\ \Test :Neotest run]] + end, +}) + +-- 8. Unlist quickfix buffers if the filetype changes. +autocmd("FileType", { + desc = "Unlist quickfist buffers", + pattern = "qf", + callback = function() vim.opt_local.buflisted = false end, +}) + +-- 9. Close all notifications on BufWritePre. +autocmd("BufWritePre", { + desc = "Close all notifications on BufWritePre", + callback = function() + require("notify").dismiss({ pending = true, silent = true }) + end, +}) + +-- ## COMMANDS -------------------------------------------------------------- + +-- 10. Testing commands +-- Aditional commands to the ones implemented in neotest. +------------------------------------------------------------------- + +-- Customize this command to work as you like +cmd("TestNodejs", function() + vim.cmd ":ProjectRoot" -- cd the project root (requires project.nvim) + vim.cmd ":TermExec cmd='npm run test'" -- convention to run tests on nodejs + -- You can generate code coverage by add this to your project's packages.json + -- "tests": "jest --coverage" +end, { desc = "Run all unit tests for the current nodejs project" }) + +-- Customize this command to work as you like +cmd("TestNodejsE2e", function() + vim.cmd ":ProjectRoot" -- cd the project root (requires project.nvim) + vim.cmd ":TermExec cmd='npm run e2e'" -- Conventional way to call e2e in nodejs (requires ToggleTerm) +end, { desc = "Run e2e tests for the current nodejs project" }) + +-- Extra commands +---------------------------------------------- + +-- Change working directory +cmd("Cwd", function() + vim.cmd ":cd %:p:h" + vim.cmd ":pwd" +end, { desc = "cd current file's directory" }) + +-- Set working directory (alias) +cmd("Swd", function() + vim.cmd ":cd %:p:h" + vim.cmd ":pwd" +end, { desc = "cd current file's directory" }) + +-- Write all buffers +cmd("WriteAllBuffers", function() + vim.cmd "wa" +end, { desc = "Write all changed buffers" }) + +-- Close all notifications +cmd("CloseNotifications", function() + require("notify").dismiss({ pending = true, silent = true }) +end, { desc = "Dismiss all notifications" }) diff --git a/dot_config/nvim/lua/base/4-mappings.lua b/dot_config/nvim/lua/base/4-mappings.lua new file mode 100644 index 0000000000000000000000000000000000000000..001dc1051d531645cc1b347e42feae48557c4040 --- /dev/null +++ b/dot_config/nvim/lua/base/4-mappings.lua @@ -0,0 +1,1616 @@ +-- Keybindings (qwerty). + +-- DESCRIPTION: +-- All mappings are defined here. + +-- Sections: +-- ## Base bindings +-- -> icons displayed on which-key.nvim +-- -> standard operations +-- -> clipboard +-- -> search highlighting +-- -> improved tabulation +-- -> improved gg +-- -> packages +-- -> buffers/tabs [buffers] +-- -> ui toggles [ui] +-- -> shifted movement keys +-- -> cmdline autocompletion +-- -> special cases + +-- ## Plugin bindings +-- -> alpha-nvim +-- -> git [git] +-- -> file browsers +-- -> session manager +-- -> smart-splits.nvim +-- -> aerial.nvim +-- -> litee-calltree.nvim +-- -> telescope.nivm [find] +-- -> toggleterm.nvim +-- -> dap.nvim [debugger] +-- -> tests [tests] +-- -> nvim-ufo +-- -> code documentation [docs] +-- -> ask chatgpt [neural] +-- -> hop.nvim +-- -> mason-lspconfig.nvim [lsp] + +-- +-- KEYBINDINGS REFERENCE +-- ------------------------------------------------------------------- +-- | Mode | Norm | Ins | Cmd | Vis | Sel | Opr | Term | Lang | +-- Command +------+-----+-----+-----+-----+-----+------+------+ +-- [nore]map | yes | - | - | yes | yes | yes | - | - | +-- n[nore]map | yes | - | - | - | - | - | - | - | +-- [nore]map! | - | yes | yes | - | - | - | - | - | +-- i[nore]map | - | yes | - | - | - | - | - | - | +-- c[nore]map | - | - | yes | - | - | - | - | - | +-- v[nore]map | - | - | - | yes | yes | - | - | - | +-- x[nore]map | - | - | - | yes | - | - | - | - | +-- s[nore]map | - | - | - | - | yes | - | - | - | +-- o[nore]map | - | - | - | - | - | yes | - | - | +-- t[nore]map | - | - | - | - | - | - | yes | - | +-- l[nore]map | - | yes | yes | - | - | - | - | yes | +-- ------------------------------------------------------------------- + +local M = {} +local utils = require "base.utils" +local get_icon = utils.get_icon +local is_available = utils.is_available +local ui = require "base.utils.ui" +local maps = require("base.utils").get_mappings_template() +local is_android = vim.fn.isdirectory('/data') == 1 -- true if on android + +-- ------------------------------------------------------------------------- +-- +-- ## Base bindings ######################################################## +-- +-- ------------------------------------------------------------------------- + +-- icons displayed on which-key.nvim --------------------------------------- +local icons = { + f = { desc = get_icon("Search", 1, true) .. "Find" }, + p = { desc = get_icon("Package", 1, true) .. "Packages" }, + l = { desc = get_icon("ActiveLSP", 1, true) .. "LSP" }, + u = { desc = get_icon("Window", 1, true) .. "UI" }, + b = { desc = get_icon("Tab", 1, true) .. "Buffers" }, + bs = { desc = get_icon("Sort", 1, true) .. "Sort Buffers" }, + c = { desc = get_icon("Run", 1, true) .. "Compiler" }, + d = { desc = get_icon("Debugger", 1, true) .. "Debugger" }, + tt = { desc = get_icon("Test", 1, true) .. "Test" }, + dc = { desc = get_icon("Docs", 1, true) .. "Docs" }, + g = { desc = get_icon("Git", 1, true) .. "Git" }, + S = { desc = get_icon("Session", 1, true) .. "Session" }, + t = { desc = get_icon("Terminal", 1, true) .. "Terminal" }, +} + +-- standard Operations ----------------------------------------------------- +maps.n["j"] = +{ "v:count == 0 ? 'gj' : 'j'", expr = true, desc = "Move cursor down" } +maps.n["k"] = +{ "v:count == 0 ? 'gk' : 'k'", expr = true, desc = "Move cursor up" } +maps.n["w"] = { "w", desc = "Save" } +maps.n["W"] = +{ function() vim.cmd "SudaWrite" end, desc = "Save as sudo" } +maps.n["n"] = { "enew", desc = "New file" } +maps.n["/"] = { "gcc", remap = true, desc = "Toggle comment line" } +maps.x["/"] = { "gc", remap = true, desc = "Toggle comment" } +maps.n["gx"] = +{ utils.open_with_program, desc = "Open the file under cursor with a program" } +maps.n[""] = { "w!", desc = "Force write" } +maps.n["|"] = { "vsplit", desc = "Vertical Split" } +maps.n["\\"] = { "split", desc = "Horizontal Split" } +maps.i[""] = { "", desc = "Enable CTRL+backsace to delete." } +maps.n["0"] = +{ "^", desc = "Go to the fist character of the line (aliases 0 to ^)" } +maps.n["q"] = { "confirm q", desc = "Quit" } +maps.n["q"] = { + function() + -- Ask user for confirmation + local choice = vim.fn.confirm("Do you really want to exit nvim?", "&Yes\n&No", 2) + if choice == 1 then + -- If user confirms, but there are still files to be saved: Ask + vim.cmd('confirm quit') + end + end, + desc = "Quit", +} +maps.n[""] = { + "", + noremap = true, + silent = true, + expr = false, + desc = "FIX: Prevent TAB from behaving like , as they share the same internal code", +} + +-- clipboard --------------------------------------------------------------- + +-- BUG: We disable these mappings on termux by default because +-- is the keycode for scrolling, and remapping it would break it. +if not is_android then + -- only useful when the option clipboard is commented on ./1-options.lua + maps.n[""] = { '"+y', desc = "Copy to cliboard" } + maps.x[""] = { '"+y', desc = "Copy to cliboard" } + maps.n[""] = { '"+ydd', desc = "Copy to clipboard and delete line" } + maps.x[""] = { '"+ydd', desc = "Copy to clipboard and delete line" } + maps.n[""] = { '"+p', desc = "Paste from clipboard" } +end + +-- Make 'c' key not copy to clipboard when changing a character. +maps.n["c"] = { '"_c', desc = "Change without yanking" } +maps.n["C"] = { '"_C', desc = "Change without yanking" } +maps.x["c"] = { '"_c', desc = "Change without yanking" } +maps.x["C"] = { '"_C', desc = "Change without yanking" } + +-- Make 'x' key not copy to clipboard when deleting a character. +maps.n["x"] = { + -- Also let's allow 'x' key to delete blank lines in normal mode. + function() + if vim.fn.col "." == 1 then + local line = vim.fn.getline "." + if line:match "^%s*$" then + vim.api.nvim_feedkeys('"_dd', "n", false) + vim.api.nvim_feedkeys("$", "n", false) + else + vim.api.nvim_feedkeys('"_x', "n", false) + end + else + vim.api.nvim_feedkeys('"_x', "n", false) + end + end, + desc = "Delete character without yanking it", +} +maps.x["x"] = { '"_x', desc = "Delete all characters in line" } + +-- Same for shifted X +maps.n["X"] = { + -- Also let's allow 'x' key to delete blank lines in normal mode. + function() + if vim.fn.col "." == 1 then + local line = vim.fn.getline "." + if line:match "^%s*$" then + vim.api.nvim_feedkeys('"_dd', "n", false) + vim.api.nvim_feedkeys("$", "n", false) + else + vim.api.nvim_feedkeys('"_X', "n", false) + end + else + vim.api.nvim_feedkeys('"_X', "n", false) + end + end, + desc = "Delete before character without yanking it", +} +maps.x["X"] = { '"_X', desc = "Delete all characters in line" } + +-- Override nvim default behavior so it doesn't auto-yank when pasting on visual mode. +maps.x["p"] = { "P", desc = "Paste content you've previourly yanked" } +maps.x["P"] = { "p", desc = "Yank what you are going to override, then paste" } + +-- search highlighting ------------------------------------------------------ +-- use ESC to clear hlsearch, while preserving its original functionality. +-- +-- TIP: If you prefer, use ENTER instead of +-- to avoid triggering it by accident. +maps.n[""] = { + function() + if vim.fn.hlexists "Search" then + vim.cmd "nohlsearch" + else + vim.api.nvim_feedkeys( + vim.api.nvim_replace_termcodes("", true, true, true), + "n", + true + ) + end + end, +} + +-- Improved tabulation ------------------------------------------------------ +maps.x[""] = { ""] = { ">gv", desc = "indent line" } +maps.x["<"] = { ""] = { ">gv", desc = "indent line" } + +-- improved gg -------------------------------------------------------------- +maps.n["gg"] = { + function() + vim.g.minianimate_disable = true + if vim.v.count > 0 then + vim.cmd("normal! " .. vim.v.count .. "gg") + else + vim.cmd "normal! gg0" + end + vim.g.minianimate_disable = false + end, + desc = "gg and go to the first position", +} +maps.n["G"] = { + function() + vim.g.minianimate_disable = true + vim.cmd "normal! G$" + vim.g.minianimate_disable = false + end, + desc = "G and go to the last position", +} +maps.x["gg"] = { + function() + vim.g.minianimate_disable = true + if vim.v.count > 0 then + vim.cmd("normal! " .. vim.v.count .. "gg") + else + vim.cmd "normal! gg0" + end + vim.g.minianimate_disable = false + end, + desc = "gg and go to the first position (visual)", +} +maps.x["G"] = { + function() + vim.g.minianimate_disable = true + vim.cmd "normal! G$" + vim.g.minianimate_disable = false + end, + desc = "G and go to the last position (visual)", +} +maps.n[""] = { -- to move to the previous position press ctrl + oo + function() + vim.g.minianimate_disable = true + vim.cmd "normal! gg0vG$" + vim.g.minianimate_disable = false + end, + desc = "Visually select all", +} + +-- packages ----------------------------------------------------------------- +-- lazy +maps.n["p"] = icons.p +maps.n["pu"] = +{ function() require("lazy").check() end, desc = "Lazy open" } +maps.n["pU"] = +{ function() require("lazy").update() end, desc = "Lazy update" } + +-- mason +if is_available "mason.nvim" then + maps.n["pm"] = { "Mason", desc = "Mason open" } + maps.n["pM"] = { "MasonUpdateAll", desc = "Mason update" } +end + +-- treesitter +if is_available "nvim-treesitter" then + maps.n["pT"] = { "TSUpdate", desc = "Treesitter update" } + maps.n["pt"] = { "TSInstallInfo", desc = "Treesitter open" } +end + +-- nvim updater +maps.n["pD"] = { "DistroUpdate", desc = "Distro update" } +maps.n["pv"] = { "DistroReadVersion", desc = "Distro version" } +maps.n["pc"] = { "DistroReadChangelog", desc = "Distro changelog" } + +-- buffers/tabs [buffers ]-------------------------------------------------- +maps.n["c"] = { -- Close window and buffer at the same time. + function() require("heirline-components.buffer").wipe() end, + desc = "Wipe buffer", +} +maps.n["C"] = { -- Close buffer keeping the window. + function() require("heirline-components.buffer").close() end, + desc = "Close buffer", +} +-- Close buffer keeping the window → Without confirmation. +-- maps.n["X"] = { +-- function() require("heirline-components.buffer").close(0, true) end, +-- desc = "Force close buffer", +-- +maps.n["ba"] = { + function() vim.cmd "wa" end, + desc = "Write all changed buffers", +} +maps.n["]b"] = { + function() + require("heirline-components.buffer").nav(vim.v.count > 0 and vim.v.count or 1) + end, + desc = "Next buffer", +} +maps.n["[b"] = { + function() + require("heirline-components.buffer").nav(-(vim.v.count > 0 and vim.v.count or 1)) + end, + desc = "Previous buffer", +} +maps.n[">b"] = { + function() + require("heirline-components.buffer").move(vim.v.count > 0 and vim.v.count or 1) + end, + desc = "Move buffer tab right", +} +maps.n[" 0 and vim.v.count or 1)) + end, + desc = "Move buffer tab left", +} + +maps.n["b"] = icons.b +maps.n["bc"] = { + function() require("heirline-components.buffer").close_all(true) end, + desc = "Close all buffers except current", +} +maps.n["bC"] = { + function() require("heirline-components.buffer").close_all() end, + desc = "Close all buffers", +} +maps.n["bb"] = { + function() + require("heirline-components.all").heirline.buffer_picker( + function(bufnr) vim.api.nvim_win_set_buf(0, bufnr) end + ) + end, + desc = "Select buffer from tabline", +} +maps.n["bd"] = { + function() + require("heirline-components.all").heirline.buffer_picker( + function(bufnr) require("heirline-components.buffer").close(bufnr) end + ) + end, + desc = "Delete buffer from tabline", +} +maps.n["bl"] = { + function() require("heirline-components.buffer").close_left() end, + desc = "Close all buffers to the left", +} +maps.n["br"] = { + function() require("heirline-components.buffer").close_right() end, + desc = "Close all buffers to the right", +} +maps.n["bs"] = icons.bs +maps.n["bse"] = { + function() require("heirline-components.buffer").sort "extension" end, + desc = "Sort by extension (buffers)", +} +maps.n["bsr"] = { + function() require("heirline-components.buffer").sort "unique_path" end, + desc = "Sort by relative path (buffers)", +} +maps.n["bsp"] = { + function() require("heirline-components.buffer").sort "full_path" end, + desc = "Sort by full path (buffers)", +} +maps.n["bsi"] = { + function() require("heirline-components.buffer").sort "bufnr" end, + desc = "Sort by buffer number (buffers)", +} +maps.n["bsm"] = { + function() require("heirline-components.buffer").sort "modified" end, + desc = "Sort by modification (buffers)", +} +maps.n["b\\"] = { + function() + require("heirline-components.all").heirline.buffer_picker(function(bufnr) + vim.cmd.split() + vim.api.nvim_win_set_buf(0, bufnr) + end) + end, + desc = "Horizontal split buffer from tabline", +} +maps.n["b|"] = { + function() + require("heirline-components.all").heirline.buffer_picker(function(bufnr) + vim.cmd.vsplit() + vim.api.nvim_win_set_buf(0, bufnr) + end) + end, + desc = "Vertical split buffer from tabline", +} + +-- quick movement aliases +maps.n[""] = { + function() + require("heirline-components.buffer").nav(vim.v.count > 0 and vim.v.count or 1) + end, + desc = "Next buffer", +} +maps.n[""] = { + function() + require("heirline-components.buffer").nav(-(vim.v.count > 0 and vim.v.count or 1)) + end, + desc = "Previous buffer", +} +maps.n[""] = { + function() vim.api.nvim_feedkeys("5j", "n", true) end, + desc = "Fast move down", +} +maps.n[""] = { + function() vim.api.nvim_feedkeys("5k", "n", true) end, + desc = "Fast move up", +} + +-- tabs +maps.n["]t"] = { function() vim.cmd.tabnext() end, desc = "Next tab" } +maps.n["[t"] = { function() vim.cmd.tabprevious() end, desc = "Previous tab" } + +-- zen mode +if is_available "zen-mode.nvim" then + maps.n["uz"] = + { function() ui.toggle_zen_mode() end, desc = "Zen mode" } +end + +-- ui toggles [ui] --------------------------------------------------------- +maps.n["u"] = icons.u +if is_available "nvim-autopairs" then + maps.n["ua"] = { ui.toggle_autopairs, desc = "Autopairs" } +end +maps.n["ub"] = { ui.toggle_background, desc = "Background" } +if is_available "nvim-cmp" then + maps.n["uc"] = { ui.toggle_cmp, desc = "Autocompletion" } +end +if is_available "nvim-colorizer.lua" then + maps.n["uC"] = + { "ColorizerToggle", desc = "color highlight" } +end +maps.n["ud"] = { ui.toggle_diagnostics, desc = "Diagnostics" } +maps.n["uD"] = { ui.set_indent, desc = "Change indent setting" } +maps.n["ug"] = { ui.toggle_signcolumn, desc = "Signcolumn" } +maps.n["ul"] = { ui.toggle_statusline, desc = "Statusline" } +maps.n["un"] = { ui.change_number, desc = "Change line numbering" } +maps.n["uP"] = { ui.toggle_paste, desc = "Paste mode" } +maps.n["us"] = { ui.toggle_spell, desc = "Spellcheck" } +maps.n["uS"] = { ui.toggle_conceal, desc = "Conceal" } +maps.n["ut"] = { ui.toggle_tabline, desc = "Tabline" } +maps.n["uu"] = { ui.toggle_url_effect, desc = "URL highlight" } +maps.n["uw"] = { ui.toggle_wrap, desc = "Wrap" } +maps.n["uy"] = { ui.toggle_buffer_syntax, desc = "Syntax highlight (buffer)" } +maps.n["uh"] = { ui.toggle_foldcolumn, desc = "Foldcolumn" } +maps.n["uN"] = +{ ui.toggle_ui_notifications, desc = "UI notifications" } +if is_available "lsp_signature.nvim" then + maps.n["up"] = { ui.toggle_lsp_signature, desc = "LSP signature" } +end +if is_available "mini.animate" then + maps.n["uA"] = { ui.toggle_animations, desc = "Animations" } +end + +-- shifted movement keys ---------------------------------------------------- +maps.n[""] = { + function() vim.api.nvim_feedkeys("7j", "n", true) end, + desc = "Fast move down", +} +maps.n[""] = { + function() vim.api.nvim_feedkeys("7k", "n", true) end, + desc = "Fast move up", +} +maps.n[""] = { + function() + local current_line = vim.fn.line "." + local total_lines = vim.fn.line "$" + local target_line = current_line + 1 + math.floor(total_lines * 0.20) + if target_line > total_lines then target_line = total_lines end + vim.api.nvim_win_set_cursor(0, { target_line, 0 }) + vim.cmd "normal! zz" + end, + desc = "Page down exactly a 20% of the total size of the buffer", +} +maps.n[""] = { + function() + local current_line = vim.fn.line "." + local target_line = current_line - 1 - math.floor(vim.fn.line "$" * 0.20) + if target_line < 1 then target_line = 1 end + vim.api.nvim_win_set_cursor(0, { target_line, 0 }) + vim.cmd "normal! zz" + end, + desc = "Page up exactly 20% of the total size of the buffer", +} + +-- cmdline autocompletion --------------------------------------------------- +maps.c[""] = { + function() return vim.fn.wildmenumode() == 1 and "" or "" end, + noremap = true, + expr = true, + desc = "Wildmenu fix for neovim bug #9953", +} +maps.c[""] = { + function() return vim.fn.wildmenumode() == 1 and "" or "" end, + noremap = true, + expr = true, + desc = "Wildmenu fix for neovim bug #9953", +} +maps.c[""] = { + function() return vim.fn.wildmenumode() == 1 and "" or "" end, + noremap = true, + expr = true, + desc = "Wildmenu fix for neovim bug #9953", +} +maps.c[""] = { + function() return vim.fn.wildmenumode() == 1 and "" or "" end, + noremap = true, + expr = true, + desc = "Wildmenu fix for neovim bug #9953", +} + +-- special cases ------------------------------------------------------------ +vim.api.nvim_create_autocmd("BufWinEnter", { + desc = "Make q close help, man, quickfix, dap floats", + callback = function(args) + local buftype = + vim.api.nvim_get_option_value("buftype", { buf = args.buf }) + if vim.tbl_contains({ "help", "nofile", "quickfix" }, buftype) then + vim.keymap.set( + "n", "q", "close", + { buffer = args.buf, silent = true, nowait = true } + ) + end + end, +}) +vim.api.nvim_create_autocmd("CmdwinEnter", { + desc = "Make q close command history (q: and q?)", + callback = function(args) + vim.keymap.set( + "n", "q", "close", + { buffer = args.buf, silent = true, nowait = true } + ) + end, +}) + +-- ------------------------------------------------------------------------- +-- +-- ## Plugin bindings +-- +-- ------------------------------------------------------------------------- + +-- alpha-nvim -------------------------------------------------------------- +if is_available "alpha-nvim" then + maps.n["h"] = { + function() + local wins = vim.api.nvim_tabpage_list_wins(0) + if #wins > 1 + and vim.api.nvim_get_option_value("filetype", { win = wins[1] }) + == "neo-tree" + then + vim.fn.win_gotoid(wins[2]) -- go to non-neo-tree window to toggle alpha + end + require("alpha").start(false, require("alpha").default_config) + vim.b.miniindentscope_disable = true + end, + desc = "Home screen", + } +end + +-- [git] ----------------------------------------------------------- +-- gitsigns.nvim +maps.n["g"] = icons.g +if is_available "gitsigns.nvim" then + maps.n["g"] = icons.g + maps.n["]g"] = + { function() require("gitsigns").next_hunk() end, desc = "Next Git hunk" } + maps.n["[g"] = { + function() require("gitsigns").prev_hunk() end, + desc = "Previous Git hunk", + } + maps.n["gl"] = { + function() require("gitsigns").blame_line() end, + desc = "View Git blame", + } + maps.n["gL"] = { + function() require("gitsigns").blame_line { full = true } end, + desc = "View full Git blame", + } + maps.n["gp"] = { + function() require("gitsigns").preview_hunk() end, + desc = "Preview Git hunk", + } + maps.n["gh"] = { + function() require("gitsigns").reset_hunk() end, + desc = "Reset Git hunk", + } + maps.n["gr"] = { + function() require("gitsigns").reset_buffer() end, + desc = "Reset Git buffer", + } + maps.n["gs"] = { + function() require("gitsigns").stage_hunk() end, + desc = "Stage Git hunk", + } + maps.n["gS"] = { + function() require("gitsigns").stage_buffer() end, + desc = "Stage Git buffer", + } + maps.n["gu"] = { + function() require("gitsigns").undo_stage_hunk() end, + desc = "Unstage Git hunk", + } + maps.n["gd"] = { + function() require("gitsigns").diffthis() end, + desc = "View Git diff", + } +end +-- git fugitive +if is_available "vim-fugitive" then + maps.n["gP"] = { + function() vim.cmd ":GBrowse" end, + desc = "Open in github ", + } +end +-- git client +if vim.fn.executable "lazygit" == 1 then -- if lazygit exists, show it + maps.n["gg"] = { + function() + local git_dir = vim.fn.finddir(".git", vim.fn.getcwd() .. ";") + if git_dir ~= "" then + vim.cmd "TermExec cmd='lazygit && exit'" + else + utils.notify("Not a git repository", vim.log.levels.WARN) + end + end, + desc = "ToggleTerm lazygit", + } +end +if vim.fn.executable "gitui" == 1 then -- if gitui exists, show it + maps.n["gg"] = { + function() + local git_dir = vim.fn.finddir(".git", vim.fn.getcwd() .. ";") + if git_dir ~= "" then + if vim.fn.executable "keychain" == 1 then + vim.cmd 'TermExec cmd="eval `keychain --eval ~/.ssh/github.key` && gitui && exit"' + else + vim.cmd "TermExec cmd='gitui && exit'" + end + else + utils.notify("Not a git repository", vim.log.levels.WARN) + end + end, + desc = "ToggleTerm gitui", + } +end + +-- file browsers ------------------------------------ +-- ranger +if is_available "rnvimr" then + maps.n["r"] = { "RnvimrToggle", desc = "Ranger" } +end + +-- neotree +if is_available "neo-tree.nvim" then + maps.n["e"] = { "Neotree toggle", desc = "Neotree" } +end + +-- session manager --------------------------------------------------------- +if is_available "neovim-session-manager" then + maps.n["S"] = icons.S + maps.n["Sl"] = { + "SessionManager! load_last_session", + desc = "Load last session", + } + maps.n["Ss"] = { + "SessionManager! save_current_session", + desc = "Save this session", + } + maps.n["Sd"] = + { "SessionManager! delete_session", desc = "Delete session" } + maps.n["Sf"] = + { "SessionManager! load_session", desc = "Search sessions" } + maps.n["S."] = { + "SessionManager! load_current_dir_session", + desc = "Load current directory session", + } +end +if is_available "resession.nvim" then + maps.n["S"] = icons.S + maps.n["Sl"] = { + function() require("resession").load "Last Session" end, + desc = "Load last session", + } + maps.n["Ss"] = + { function() require("resession").save() end, desc = "Save this session" } + maps.n["St"] = { + function() require("resession").save_tab() end, + desc = "Save this tab's session", + } + maps.n["Sd"] = + { function() require("resession").delete() end, desc = "Delete a session" } + maps.n["Sf"] = + { function() require("resession").load() end, desc = "Load a session" } + maps.n["S."] = { + function() + require("resession").load(vim.fn.getcwd(), { dir = "dirsession" }) + end, + desc = "Load current directory session", + } +end + +-- smart-splits.nivm +if is_available "smart-splits.nvim" then + maps.n[""] = { + function() require("smart-splits").move_cursor_left() end, + desc = "Move to left split", + } + maps.n[""] = { + function() require("smart-splits").move_cursor_down() end, + desc = "Move to below split", + } + maps.n[""] = { + function() require("smart-splits").move_cursor_up() end, + desc = "Move to above split", + } + maps.n[""] = { + function() require("smart-splits").move_cursor_right() end, + desc = "Move to right split", + } + maps.n[""] = { + function() require("smart-splits").resize_up() end, + desc = "Resize split up", + } + maps.n[""] = { + function() require("smart-splits").resize_down() end, + desc = "Resize split down", + } + maps.n[""] = { + function() require("smart-splits").resize_left() end, + desc = "Resize split left", + } + maps.n[""] = { + function() require("smart-splits").resize_right() end, + desc = "Resize split right", + } +else + maps.n[""] = { "h", desc = "Move to left split" } + maps.n[""] = { "j", desc = "Move to below split" } + maps.n[""] = { "k", desc = "Move to above split" } + maps.n[""] = { "l", desc = "Move to right split" } + maps.n[""] = { "resize -2", desc = "Resize split up" } + maps.n[""] = { "resize +2", desc = "Resize split down" } + maps.n[""] = + { "vertical resize -2", desc = "Resize split left" } + maps.n[""] = + { "vertical resize +2", desc = "Resize split right" } +end + +-- aerial.nvimm ------------------------------------------------------------ +if is_available "aerial.nvim" then + maps.n["i"] = + { function() require("aerial").toggle() end, desc = "Aerial" } +end + +-- letee-calltree.nvimm ------------------------------------------------------------ +if is_available "litee-calltree.nvim" then + -- For every buffer, look for the one with filetype "calltree" and focus it. + local calltree_delay = 1500 -- first run? wait a bit longer. + local function focus_calltree() + -- Note: No go to the previous cursor position, press ctrl+i / ctrl+o + vim.defer_fn(function() + for _, win in ipairs(vim.api.nvim_list_wins()) do + local buf = vim.api.nvim_win_get_buf(win) + local ft = vim.api.nvim_get_option_value('filetype', { buf = buf }) + + if ft == "calltree" then + vim.api.nvim_set_current_win(win) + return true + end + end + end, calltree_delay) + calltree_delay = 100 + end + maps.n["gj"] = { + function() + vim.lsp.buf.incoming_calls() + focus_calltree() + end, + desc = "Call tree (incoming)" + } + maps.n["gJ"] = + { + function() + vim.lsp.buf.outgoing_calls() + focus_calltree() + end, + desc = "Call tree (outgoing)" + } +end + +-- telescope.nvim [find] ---------------------------------------------------- +if is_available "telescope.nvim" then + maps.n["f"] = icons.f + maps.n["gb"] = { + function() require("telescope.builtin").git_branches() end, + desc = "Git branches", + } + maps.n["gc"] = { + function() + require("telescope.builtin").git_commits() + end, + desc = "Git commits (repository)" + } + maps.n["gC"] = { + function() + require("telescope.builtin").git_bcommits() + end, + desc = "Git commits (current file)" + } + maps.n["gt"] = { + function() require("telescope.builtin").git_status() end, + desc = "Git status", + } + maps.n["f"] = { + function() require("telescope.builtin").resume() end, + desc = "Resume previous search", + } + maps.n["f'"] = { + function() require("telescope.builtin").marks() end, + desc = "Find marks", + } + maps.n["fa"] = { + function() + local cwd = vim.fn.stdpath "config" .. "/.." + local search_dirs = { vim.fn.stdpath "config" } + if #search_dirs == 1 then cwd = search_dirs[1] end -- if only one directory, focus cwd + require("telescope.builtin").find_files { + prompt_title = "Config Files", + search_dirs = search_dirs, + cwd = cwd, + follow = true, + } -- call telescope + end, + desc = "Find nvim config files", + } + maps.n["fB"] = { + function() require("telescope.builtin").buffers() end, + desc = "Find buffers", + } + maps.n["fw"] = { + function() require("telescope.builtin").grep_string() end, + desc = "Find word under cursor in project", + } + maps.n["fC"] = { + function() require("telescope.builtin").commands() end, + desc = "Find commands", + } + -- Let's disable this. It is way too imprecise. Use rnvimr instead. + -- maps.n["ff"] = { + -- function() + -- require("telescope.builtin").find_files { hidden = true, no_ignore = true } + -- end, + -- desc = "Find all files", + -- } + -- maps.n["fF"] = { + -- function() require("telescope.builtin").find_files() end, + -- desc = "Find files (no hidden)", + -- } + maps.n["fh"] = { + function() require("telescope.builtin").help_tags() end, + desc = "Find help", + } + maps.n["fk"] = { + function() require("telescope.builtin").keymaps() end, + desc = "Find keymaps", + } + maps.n["fm"] = { + function() require("telescope.builtin").man_pages() end, + desc = "Find man", + } + if is_available "nvim-notify" then + maps.n["fn"] = { + function() require("telescope").extensions.notify.notify() end, + desc = "Find notifications", + } + end + maps.n["fo"] = { + function() require("telescope.builtin").oldfiles() end, + desc = "Find recent", + } + maps.n["fv"] = { + function() require("telescope.builtin").registers() end, + desc = "Find vim registers", + } + maps.n["ft"] = { + function() + -- load color schemes before listing them + pcall(vim.api.nvim_command, "doautocmd User LoadColorSchemes") + + -- Open telescope + pcall(require("telescope.builtin").colorscheme, { + enable_preview = true, + ignore_builtins = true + }) + end, + desc = "Find themes", + } + maps.n["ff"] = { + function() + require("telescope.builtin").live_grep { + additional_args = function(args) + return vim.list_extend(args, { "--hidden", "--no-ignore" }) + end, + } + end, + desc = "Find words in project", + } + maps.n["fF"] = { + function() require("telescope.builtin").live_grep() end, + desc = "Find words in project (no hidden)", + } + maps.n["f/"] = { + function() require("telescope.builtin").current_buffer_fuzzy_find() end, + desc = "Find words in current buffer" + } + + -- Some lsp keymappings are here because they depend on telescope + maps.n["l"] = icons.l + maps.n["ls"] = { + function() + local aerial_avail, _ = pcall(require, "aerial") + if aerial_avail then + require("telescope").extensions.aerial.aerial() + else + require("telescope.builtin").lsp_document_symbols() + end + end, + desc = "Search symbol in buffer", -- Useful to find every time a variable is assigned. + } + maps.n["gs"] = { + function() + local aerial_avail, _ = pcall(require, "aerial") + if aerial_avail then + require("telescope").extensions.aerial.aerial() + else + require("telescope.builtin").lsp_document_symbols() + end + end, + desc = "Search symbol in buffer", -- Useful to find every time a variable is assigned. + } + + -- extra - project.nvim + if is_available "project.nvim" then + maps.n["fp"] = { + function() vim.cmd "Telescope projects" end, + desc = "Find project", + } + end + + -- extra - spectre.nvim (search and replace in project) + if is_available "nvim-spectre" then + maps.n["fr"] = { + function() require("spectre").toggle() end, + desc = "Find and replace word in project", + } + maps.n["fb"] = { + function() require("spectre").toggle { path = vim.fn.expand "%:t:p" } end, + desc = "Find and replace word in buffer", + } + end + + -- extra - luasnip + if is_available "LuaSnip" and is_available "telescope-luasnip.nvim" then + maps.n["fs"] = { + function() require("telescope").extensions.luasnip.luasnip {} end, + desc = "Find snippets", + } + end + + -- extra - nvim-neoclip (neovim internal clipboard) + -- Specially useful if you disable the shared clipboard in options. + if is_available "nvim-neoclip.lua" then + maps.n["fy"] = { + function() require("telescope").extensions.neoclip.default() end, + desc = "Find yank history", + } + maps.n["fq"] = { + function() require("telescope").extensions.macroscope.default() end, + desc = "Find macro history", + } + end + + -- extra - undotree + if is_available "telescope-undo.nvim" then + maps.n["fu"] = { + function() require("telescope").extensions.undo.undo() end, + desc = "Find in undo tree", + } + end + + -- extra - compiler + if is_available "compiler.nvim" and is_available "overseer.nvim" then + maps.n["m"] = icons.c + maps.n["mm"] = { + function() vim.cmd "CompilerOpen" end, + desc = "Open compiler", + } + maps.n["mr"] = { + function() vim.cmd "CompilerRedo" end, + desc = "Compiler redo", + } + maps.n["mt"] = { + function() vim.cmd "CompilerToggleResults" end, + desc = "compiler results", + } + maps.n[""] = { + function() vim.cmd "CompilerOpen" end, + desc = "Open compiler", + } + maps.n[""] = { + function() vim.cmd "CompilerRedo" end, + desc = "Compiler redo", + } + maps.n[""] = { + function() vim.cmd "CompilerToggleResults" end, + desc = "compiler resume", + } + end +end + +-- toggleterm.nvim ---------------------------------------------------------- +if is_available "toggleterm.nvim" then + maps.n["t"] = icons.t + maps.n["tt"] = + { "ToggleTerm direction=float", desc = "ToggleTerm float" } + maps.n["th"] = { + "ToggleTerm size=10 direction=horizontal", + desc = "Toggleterm horizontal split", + } + maps.n["tv"] = { + "ToggleTerm size=80 direction=vertical", + desc = "Toggleterm vertical split", + } + maps.n[""] = { "ToggleTerm", desc = "terminal" } + maps.t[""] = maps.n[""] + maps.n[""] = maps.n[""] -- requires terminal that supports binding + maps.t[""] = maps.n[""] -- requires terminal that supports binding +end + +-- extra - improved terminal navigation +maps.t[""] = +{ "wincmd h", desc = "Terminal left window navigation" } +maps.t[""] = +{ "wincmd j", desc = "Terminal down window navigation" } +maps.t[""] = +{ "wincmd k", desc = "Terminal up window navigation" } +maps.t[""] = +{ "wincmd l", desc = "Terminal right window navigation" } + +-- dap.nvim [debugger] ----------------------------------------------------- +-- Depending your terminal some F keys may not work. To fix it: +-- modified function keys found with `showkey -a` in the terminal to get key code +-- run `nvim -V3log +quit` and search through the "Terminal info" in the `log` file for the correct keyname +if is_available "nvim-dap" then + maps.n["d"] = icons.d + maps.x["d"] = icons.d + + -- F keys + maps.n[""] = { + function() + require("dap").continue() + end, + desc = "Debugger: Start" + } + maps.n[""] = + { function() require("dap").terminate() end, desc = "Debugger: Stop" } + maps.n[""] = { + function() require("dap").restart_frame() end, desc = "Debugger: Restart" } + maps.n[""] = { + function() require("dap").toggle_breakpoint() end, desc = "Debugger: Toggle Breakpoint" } + maps.n[""] = { + function() + vim.ui.input({ prompt = "Condition: " }, function(condition) + if condition then require("dap").set_breakpoint(condition) end + end) + end, + desc = "Debugger: Conditional Breakpoint", + } + maps.n[""] = + { function() require("dap").step_over() end, desc = "Debugger: Step Over" } + maps.n[""] = + { function() require("dap").step_back() end, desc = "Debugger: Step Back" } + maps.n[""] = + { function() require("dap").step_into() end, desc = "Debugger: Step Into" } + maps.n[""] = + { function() require("dap").step_out() end, desc = "Debugger: Step Out" } + + -- Space + d + maps.n["db"] = { + function() require("dap").toggle_breakpoint() end, + desc = "Breakpoint (F9)", + } + maps.n["dB"] = { + function() require("dap").clear_breakpoints() end, + desc = "Clear Breakpoints", + } + maps.n["dc"] = + { function() require("dap").continue() end, desc = "Start/Continue (F5)" } + maps.n["dC"] = { + function() + vim.ui.input({ prompt = "Condition: " }, function(condition) + if condition then require("dap").set_breakpoint(condition) end + end) + end, + desc = "Conditional Breakpoint (S-F9)", + } + maps.n["do"] = + { function() require("dap").step_over() end, desc = "Step Over (F10)" } + maps.n["do"] = + { function() require("dap").step_back() end, desc = "Step Back (S-F10)" } + maps.n["db"] = + { function() require("dap").step_into() end, desc = "Step Into (F11)" } + maps.n["dO"] = + { function() require("dap").step_out() end, desc = "Step Out (S-F11)" } + maps.n["dq"] = + { function() require("dap").close() end, desc = "Close Session" } + maps.n["dQ"] = { + function() require("dap").terminate() end, + desc = "Terminate Session (S-F5)", + } + maps.n["dp"] = + { function() require("dap").pause() end, desc = "Pause" } + maps.n["dr"] = + { function() require("dap").restart_frame() end, desc = "Restart (C-F5)" } + maps.n["dR"] = + { function() require("dap").repl.toggle() end, desc = "REPL" } + maps.n["ds"] = + { function() require("dap").run_to_cursor() end, desc = "Run To Cursor" } + + if is_available "nvim-dap-ui" then + maps.n["dE"] = { + function() + vim.ui.input({ prompt = "Expression: " }, function(expr) + if expr then require("dapui").eval(expr, { enter = true }) end + end) + end, + desc = "Evaluate Input", + } + maps.x["dE"] = + { function() require("dapui").eval() end, desc = "Evaluate Input" } + maps.n["du"] = + { function() require("dapui").toggle() end, desc = "Debugger UI" } + maps.n["dh"] = { + function() require("dap.ui.widgets").hover() end, + desc = "Debugger Hover", + } + end +end + +-- testing [tests] ------------------------------------------------- +-- neotest +maps.n["T"] = icons.tt +maps.x["T"] = icons.tt +if is_available "neotest" then + maps.n["Tu"] = { + function() require("neotest").run.run() end, + desc = "Unit", + } + maps.n["Ts"] = { + function() require("neotest").run.stop() end, + desc = "Stop unit", + } + maps.n["Tf"] = { + function() require("neotest").run.run(vim.fn.expand "%") end, + desc = "File", + } + maps.n["Td"] = { + function() require("neotest").run.run { strategy = "dap" } end, + desc = "Unit in debugger", + } + maps.n["Tt"] = { + function() require("neotest").summary.toggle() end, + desc = "Neotest summary", + } + maps.n["TT"] = { + function() require("neotest").output_panel.toggle() end, + desc = "Output panel", + } +end + +-- Extra - nvim-coverage +-- Your project must generate coverage/lcov.info for this to work. +-- +-- On jest, make sure your packages.json file has this: +-- "test": "jest --coverage" +-- +-- If you use other framework or language, refer to nvim-coverage docs: +-- https://github.com/andythigpen/nvim-coverage/blob/main/doc/nvim-coverage.txt +if is_available "nvim-coverage" then + maps.n["Tc"] = { + function() + require("coverage").load(false) + require("coverage").summary() + end, + desc = "Coverage", + } + maps.n["TC"] = { + function() + ui.toggle_coverage_signs() + end, + desc = "Coverage signs (toggle)", + } +end + +-- Extra - nodejs testing commands +maps.n["Ta"] = { + function() vim.cmd "TestNodejs" end, + desc = "All", +} +maps.n["Te"] = { + function() vim.cmd "TestNodejsE2e" end, + desc = "E2e", +} + +-- nvim-ufo [code folding] -------------------------------------------------- +if is_available "nvim-ufo" then + maps.n["zR"] = + { function() require("ufo").openAllFolds() end, desc = "Open all folds" } + maps.n["zM"] = + { function() require("ufo").closeAllFolds() end, desc = "Close all folds" } + maps.n["zr"] = { + function() require("ufo").openFoldsExceptKinds() end, + desc = "Fold less", + } + maps.n["zm"] = + { function() require("ufo").closeFoldsWith() end, desc = "Fold more" } + maps.n["zp"] = { + function() require("ufo").peekFoldedLinesUnderCursor() end, + desc = "Peek fold", + } + maps.n["zn"] = + { + function() require("ufo").openFoldsExceptKinds({ 'comment' }) end, + desc = "Fold comments" + } + maps.n["zN"] = + { + function() require("ufo").openFoldsExceptKinds({ 'region' }) end, + desc = "Fold region" + } +end + +-- code docmentation [docs] ------------------------------------------------- + +if is_available "markdown-preview.nivm" or is_available "markmap.nvim" or is_available "dooku.nvim" then + maps.n["D"] = icons.dc + + -- Markdown preview + if is_available "markdown-preview.nvim" then + maps.n["Dp"] = { + function() vim.cmd "MarkdownPreview" end, + desc = "Markdown preview", + } + end + + -- Markdown Mindmap + if is_available "markmap.nvim" then + maps.n["Dm"] = { + function() + if is_android then + vim.cmd "MarkmapWatch" + else + vim.cmd "MarkmapOpen" + end + end, + desc = "Markmap", + } + end + + if is_available "dooku.nvim" then + maps.n["Dd"] = { + function() vim.cmd ":DookuGenerate" end, + desc = "Open documentation", + } + end +end + +-- [neural] ----------------------------------------------------------------- +if is_available "neural" or is_available "copilot" then + maps.n["a"] = { + function() require("neural").prompt() end, + desc = "Ask chatgpt", + } +end + +-- hop.nivm ---------------------------------------------------------------- +if is_available "hop.nvim" then + -- Note that Even though we are using ENTER for hop, you can still select items + -- from special menus like 'quickfix', 'q?' and 'q:' with . + + maps.n[""] = { -- The terminal undersand C-m and ENTER as the same key. + function() + require("hop") + vim.cmd("silent! HopWord") + end, + desc = "Hop to word", + } + maps.x[""] = { -- The terminal undersand C-m and ENTER as the same key. + function() + require("hop") + vim.cmd("silent! HopWord") + end, + desc = "Hop to word", + } +end + +-- mason-lspconfig.nvim [lsp] ------------------------------------------------- +-- WARNING: Don't delete this section, or you won't have LSP keymappings. + +--A function we call from the script to start lsp. +--@return table lsp_mappings +function M.lsp_mappings(client, bufnr) + -- Helper function to check if any active LSP clients + -- given a filter provide a specific capability. + -- @param capability string The server capability to check for (example: "documentFormattingProvider"). + -- @param filter vim.lsp.get_clients.filter|nil A valid get_clients filter (see function docs). + -- @return boolean # `true` if any of the clients provide the capability. + local function has_capability(capability, filter) + for _, lsp_client in ipairs(vim.lsp.get_clients(filter)) do + if lsp_client.supports_method(capability) then return true end + end + return false + end + + local lsp_mappings = require("base.utils").get_mappings_template() + + -- Diagnostics + lsp_mappings.n["ld"] = { function() vim.diagnostic.open_float() end, desc = "Hover diagnostics" } + lsp_mappings.n["[d"] = { function() + -- TODO: Delete after dropping nvim 0.10 support. + if vim.fn.has('nvim-0.11') == 1 then vim.diagnostic.jump({ count = -1 }) + else vim.diagnostic.goto_prev() end end, desc = "Previous diagnostic" + } + lsp_mappings.n["]d"] = { function() + -- TODO: Delete after dropping nvim 0.10 support. + if vim.fn.has('nvim-0.11') == 1 then vim.diagnostic.jump({ count = 1 }) + else vim.diagnostic.goto_next() end end, desc = "Next diagnostic" } + + -- Diagnostics + lsp_mappings.n["gl"] = { function() vim.diagnostic.open_float() end, desc = "Hover diagnostics" } + if is_available "telescope.nvim" then + lsp_mappings.n["lD"] = + { function() require("telescope.builtin").diagnostics() end, desc = "Diagnostics" } + end + + -- LSP info + if is_available "mason-lspconfig.nvim" then + lsp_mappings.n["li"] = { "LspInfo", desc = "LSP information" } + end + + if is_available "none-ls.nvim" then + lsp_mappings.n["lI"] = { "NullLsInfo", desc = "Null-ls information" } + end + + -- Code actions + lsp_mappings.n["la"] = { + function() vim.lsp.buf.code_action() end, + desc = "LSP code action", + } + lsp_mappings.v["la"] = lsp_mappings.n["la"] + + -- Codelens + utils.add_autocmds_to_buffer("lsp_codelens_refresh", bufnr, { + events = { "InsertLeave" }, + desc = "Refresh codelens", + callback = function(args) + if client.supports_method "textDocument/codeLens" then + if vim.g.codelens_enabled then vim.lsp.codelens.refresh({ bufnr = args.buf }) end + end + end, + }) + if client.supports_method "textDocument/codeLens" then -- on LspAttach + if vim.g.codelens_enabled then vim.lsp.codelens.refresh({ bufnr = 0 }) end + end + + lsp_mappings.n["ll"] = { + function() + vim.lsp.codelens.run() + vim.lsp.codelens.refresh({ bufnr = 0 }) + end, + desc = "LSP CodeLens run", + } + lsp_mappings.n["uL"] = { + function() ui.toggle_codelens() end, + desc = "CodeLens", + } + + -- Formatting + local formatting = require("base.utils.lsp").formatting + lsp_mappings.n["lf"] = { + function() + vim.lsp.buf.format(M.format_opts) + vim.cmd('checktime') -- update buffer to reflect changes. + end, + desc = "Format buffer", + } + lsp_mappings.v["lf"] = lsp_mappings.n["lf"] + + vim.api.nvim_buf_create_user_command( + bufnr, + "Format", + function() vim.lsp.buf.format(M.format_opts) end, + { desc = "Format file with LSP" } + ) + local autoformat = formatting.format_on_save + local filetype = vim.api.nvim_get_option_value("filetype", { buf = bufnr }) + if + autoformat.enabled + and (vim.tbl_isempty(autoformat.allow_filetypes or {}) or vim.tbl_contains(autoformat.allow_filetypes, filetype)) + and (vim.tbl_isempty(autoformat.ignore_filetypes or {}) or not vim.tbl_contains(autoformat.ignore_filetypes, filetype)) + then + utils.add_autocmds_to_buffer("lsp_auto_format", bufnr, { + events = "BufWritePre", + desc = "Autoformat on save", + callback = function() + if not has_capability("textDocument/formatting", { bufnr = bufnr }) then + utils.del_autocmds_from_buffer("lsp_auto_format", bufnr) + return + end + local autoformat_enabled = vim.b.autoformat_enabled + if autoformat_enabled == nil then autoformat_enabled = vim.g.autoformat_enabled end + if autoformat_enabled and ((not autoformat.filter) or autoformat.filter(bufnr)) then + vim.lsp.buf.format(vim.tbl_deep_extend("force", M.format_opts, { bufnr = bufnr })) + end + end, + }) + lsp_mappings.n["uf"] = { + function() require("base.utils.ui").toggle_buffer_autoformat() end, + desc = "Autoformatting (buffer)", + } + lsp_mappings.n["uF"] = { + function() require("base.utils.ui").toggle_autoformat() end, + desc = "Autoformatting (global)", + } + end + + -- Highlight references when cursor holds + utils.add_autocmds_to_buffer("lsp_document_highlight", bufnr, { + { + events = { "CursorHold", "CursorHoldI" }, + desc = "highlight references when cursor holds", + callback = function() + if has_capability("textDocument/documentHighlight", { bufnr = bufnr }) then + vim.lsp.buf.document_highlight() + end + end, + }, + { + events = { "CursorMoved", "CursorMovedI", "BufLeave" }, + desc = "clear references when cursor moves", + callback = function() vim.lsp.buf.clear_references() end, + }, + }) + + -- Other LSP mappings + lsp_mappings.n["lL"] = { + function() vim.api.nvim_command(':LspRestart') end, + desc = "LSP refresh", + } + + -- Goto definition / declaration + lsp_mappings.n["gd"] = { + function() vim.lsp.buf.definition() end, + desc = "Goto definition of current symbol", + } + lsp_mappings.n["gD"] = { + function() vim.lsp.buf.declaration() end, + desc = "Goto declaration of current symbol", + } + + -- Goto implementation + lsp_mappings.n["gI"] = { + function() vim.lsp.buf.implementation() end, + desc = "Goto implementation of current symbol", + } + + -- Goto type definition + lsp_mappings.n["gT"] = { + function() vim.lsp.buf.type_definition() end, + desc = "Goto definition of current type", + } + + -- Goto references + lsp_mappings.n["lR"] = { + function() vim.lsp.buf.references() end, + desc = "Hover references", + } + lsp_mappings.n["gr"] = { + function() vim.lsp.buf.references() end, + desc = "References of current symbol", + } + + -- Goto help + lsp_mappings.n["gh"] = { + function() vim.lsp.buf.hover() end, + desc = "Hover help", + } + lsp_mappings.n["gH"] = { + function() vim.lsp.buf.signature_help() end, + desc = "Signature help", + } + + lsp_mappings.n["lh"] = { + function() vim.lsp.buf.hover() end, + desc = "Hover help", + } + lsp_mappings.n["lH"] = { + function() vim.lsp.buf.signature_help() end, + desc = "Signature help", + } + + -- Goto man + lsp_mappings.n["gm"] = { + function() vim.api.nvim_feedkeys("K", "n", false) end, + desc = "Hover man", + } + lsp_mappings.n["lm"] = { + function() vim.api.nvim_feedkeys("K", "n", false) end, + desc = "Hover man", + } + + -- Rename symbol + lsp_mappings.n["lr"] = { + function() vim.lsp.buf.rename() end, + desc = "Rename current symbol", + } + + -- Toggle inlay hints + if vim.b.inlay_hints_enabled == nil then vim.b.inlay_hints_enabled = vim.g.inlay_hints_enabled end + if vim.b.inlay_hints_enabled then vim.lsp.inlay_hint.enable(true, { bufnr = bufnr }) end + lsp_mappings.n["uH"] = { + function() require("base.utils.ui").toggle_buffer_inlay_hints(bufnr) end, + desc = "LSP inlay hints (buffer)", + } + + -- Toggle semantic tokens + if vim.g.semantic_tokens_enabled then + vim.b[bufnr].semantic_tokens_enabled = true + lsp_mappings.n["uY"] = { + function() require("base.utils.ui").toggle_buffer_semantic_tokens(bufnr) end, + desc = "LSP semantic highlight (buffer)", + } + else + client.server_capabilities.semanticTokensProvider = nil + end + + -- LSP based search + lsp_mappings.n["lS"] = { function() vim.lsp.buf.workspace_symbol() end, desc = "Search symbol in workspace" } + lsp_mappings.n["gS"] = { function() vim.lsp.buf.workspace_symbol() end, desc = "Search symbol in workspace" } + + -- LSP telescope + if is_available "telescope.nvim" then -- setup telescope mappings if available + if lsp_mappings.n.gd then lsp_mappings.n.gd[1] = function() require("telescope.builtin").lsp_definitions() end end + if lsp_mappings.n.gI then + lsp_mappings.n.gI[1] = function() require("telescope.builtin").lsp_implementations() end + end + if lsp_mappings.n.gr then lsp_mappings.n.gr[1] = function() require("telescope.builtin").lsp_references() end end + if lsp_mappings.n["lR"] then + lsp_mappings.n["lR"][1] = function() require("telescope.builtin").lsp_references() end + end + if lsp_mappings.n.gy then + lsp_mappings.n.gy[1] = function() require("telescope.builtin").lsp_type_definitions() end + end + if lsp_mappings.n["lS"] then + lsp_mappings.n["lS"][1] = function() + vim.ui.input({ prompt = "Symbol Query: (leave empty for word under cursor)" }, function(query) + if query then + -- word under cursor if given query is empty + if query == "" then query = vim.fn.expand "" end + require("telescope.builtin").lsp_workspace_symbols { + query = query, + prompt_title = ("Find word (%s)"):format(query), + } + end + end) + end + end + if lsp_mappings.n["gS"] then + lsp_mappings.n["gS"][1] = function() + vim.ui.input({ prompt = "Symbol Query: (leave empty for word under cursor)" }, function(query) + if query then + -- word under cursor if given query is empty + if query == "" then query = vim.fn.expand "" end + require("telescope.builtin").lsp_workspace_symbols { + query = query, + prompt_title = ("Find word (%s)"):format(query), + } + end + end) + end + end + end + + return lsp_mappings +end + +utils.set_mappings(maps) +return M diff --git a/dot_config/nvim/lua/base/health.lua b/dot_config/nvim/lua/base/health.lua new file mode 100644 index 0000000000000000000000000000000000000000..82fb96bf9ec1e1c811a0b1d227e058f2014f22b0 --- /dev/null +++ b/dot_config/nvim/lua/base/health.lua @@ -0,0 +1,270 @@ +-- Command to check if you have the required dependencies to use NormalNvim. +-- +-- DESCRIPTION: +-- To use it run the command :healthcheck base + +local M = {} + +local health = { + start = vim.health.start or vim.health.report_start, + ok = vim.health.ok or vim.health.report_ok, + warn = vim.health.warn or vim.health.report_warn, + error = vim.health.error or vim.health.report_error, + info = vim.health.info or vim.health.report_info, +} + +function M.check() + health.start "NormalNvim" + + health.info( + "NormalNvim Version: " .. require("distroupdate.utils.updater").version(true) + ) + health.info( + "Neovim Version: v" + .. vim.fn.matchstr(vim.fn.execute "version", "NVIM v\\zs[^\n]*") + ) + + if vim.version().prerelease then + health.warn "Neovim nightly is not officially supported and may have breaking changes" + elseif vim.fn.has "nvim-0.9" == 1 then + health.ok "Using stable Neovim >= 0.9.0" + else + health.error "Neovim >= 0.9.0 is required" + end + + -- Checks to perform. + local programs = { + { + cmd = { "git" }, + type = "error", + msg = "Used for core functionality such as updater and plugin management.", + }, + { + cmd = { "luarocks" }, + type = "error", + msg = "Used for core functionality such as updater and plugin management.", + }, + { + cmd = { "node" }, + type = "error", + msg = "Used for core functionality such as updater and plugin management.", + }, + { + cmd = { "yarn" }, + type = "error", + msg = "Used for core functionality such as updater and plugin management.", + }, + { + cmd = { "cargo" }, + type = "error", + msg = "Used by nvim-spectre to install oxi. Also by dooku.nvim to generate rust html docs.", + }, + { + cmd = { "markmap" }, + type = "warn", + msg = "Used by markmap.nvim. Make sure yarn is in your PATH. To learn how check markmap.nvim github page.", + }, + { + cmd = { "fd" }, + type = "error", + msg = "Used for nvim-spectre to find using fd.", + }, + { + cmd = { "lazygit" }, + type = "warn", + msg = "Used for mappings to pull up git TUI (Optional)", + }, + { + cmd = { "gitui" }, + type = "warn", + msg = "Used for mappings to pull up git TUI (Optional)", + }, + { + cmd = { "pynvim" }, + type = "warn", + msg = + "Used to enable ranger file browser (optional)\nNOTE: checkhealth won't detect this correctly, but you can ensure it is installed with 'pip list | grep pynvim'.", + }, + { + cmd = { "ranger" }, + type = "warn", + msg = "Used to enable ranger file browser (Optional)", + }, + { + cmd = { "delta" }, + type = "warn", + msg = "Used by undotree to show a diff (Optional)", + }, + { + cmd = { "grcov" }, + type = "warn", + msg = "Used to show code coverage (Optional)", + }, + { + cmd = { "grcov" }, + type = "warn", + msg = "Used to show code coverage (Optional)", + }, + { + cmd = { "jest" }, + type = "warn", + msg = "Used to run typescript and javascript tests (Optional)", + }, + { + cmd = { "pytest" }, + type = "warn", + msg = "Used to run python tests (Optional)", + }, + { + cmd = { "cargo nextest" }, + type = "warn", + msg = + "Used to run rust tests (optional)\nNOTE: checkhealth won't detect this correctly, but you can confirm it works correctly with 'cargo nextest'.", + }, + { + cmd = { "nunit" }, + type = "warn", + msg = + "Used to run C# tests (optional)\nNOTE: There is no way to install this system wide. To use it you must add it to your dotnet C# project: 'dotnet add package NUnit NUnit3TestAdapter'.", + }, + { + cmd = { "csc" }, + type = "warn", + msg = "Used by compiler.nvim to compile non dotnet C# files (Optional)", + }, + { + cmd = { "mono" }, + type = "warn", + msg = "Used by compiler.nvim to run non dotnet C# files. (Optional)", + }, + { + cmd = { "dotnet" }, + type = "warn", + msg = + "Used by compiler.nvim and DAP to operate with dotnet projects (optional)\nNOTE: Make sure you also have the system package dotnet-sdk installed.", + }, + { + cmd = { "java" }, + type = "warn", + msg = "Used by compiler.nvim and dap to operate with java (Optional)", + }, + { + cmd = { "javac" }, + type = "warn", + msg = "Used by compiler.nvim to compile java (Optional)", + }, + { + cmd = { "nasm" }, + type = "warn", + msg = "Used by compiler.nvim to compile assembly x86_64 (Optional)", + }, + + { + cmd = { "gcc" }, + type = "warn", + msg = "Used by compiler.nvim to compile C (Optional)", + }, + { + cmd = { "g++" }, + type = "warn", + msg = "Used by compiler.nvim to compile C++ (Optional)", + }, + { + cmd = { "elixir" }, + type = "warn", + msg = "Used by compiler.nvim to compile elixir (optional)", + }, + { + cmd = { "Rscript" }, + type = "warn", + msg = "Used by compiler.nvim to interpretate R (Optional)", + }, + { + cmd = { "python" }, + type = "warn", + msg = "Used by compiler.nvim to interpretate python (Optional)", + }, + { + cmd = { "nuitka3" }, + type = "warn", + msg = "Used by compiler.nvim to compile python to machine code (Optional)", + }, + { + cmd = { "pyinstaller" }, + type = "warn", + msg = "Used by compiler.nvim to compile python to bytecode (Optional)", + }, + { + cmd = { "ruby" }, + type = "warn", + msg = "Used by compiler.nvim to interpretate ruby (optional)", + }, + { + cmd = { "perl" }, + type = "warn", + msg = "Used by compiler.nvim to interpretate perl (optional)", + }, + { + cmd = { "swiftc" }, + type = "warn", + msg = "Used by compiler.nvim to compile swift (optional)", + }, + { + cmd = { "swift" }, + type = "warn", + msg = "Used by compiler.nvim to compile swift (optional)", + }, + { + cmd = { "gfortran" }, + type = "warn", + msg = "Used by compiler.nvim to compile fortran (optional)" + }, + { + cmd = { "fpm" }, + type = "warn", + msg = "Used by compiler.nvim to compile fortran (optional)" + }, + { + cmd = { "go" }, + type = "warn", + msg = "Used by compiler.nvim to compile go (optional)", + }, + { + cmd = { "godoc" }, + type = "warn", + msg = + "Used by dooku.nvim to generate go html docs\nNOTE: If you have it installed but you can't run it on the terminal, ensure you have added 'go' to your OS path (optional)", + }, + { + cmd = { "doxygen" }, + type = "warn", + msg = "Used by dooku.nvim to generate c/c++/python/java html docs (optional)", + }, + } + + -- Actually perform the checks we defined above. + for _, program in ipairs(programs) do + if type(program.cmd) == "string" then program.cmd = { program.cmd } end + local name = table.concat(program.cmd, "/") + local found = false + for _, cmd in ipairs(program.cmd) do + if vim.fn.executable(cmd) == 1 then + name = cmd + found = true + break + end + end + + if found then + health.ok(("`%s` is installed: %s"):format(name, program.msg)) + else + health[program.type]( + ("`%s` is not installed: %s"):format(name, program.msg) + ) + end + end + health.info("") + health.info("Write `:bw` to close `:checkhealth` gracefully.") +end + +return M diff --git a/dot_config/nvim/lua/base/icons/nerd_font.lua b/dot_config/nvim/lua/base/icons/nerd_font.lua new file mode 100644 index 0000000000000000000000000000000000000000..de84933832256773c75edf2fcdf63d5d8c30666f --- /dev/null +++ b/dot_config/nvim/lua/base/icons/nerd_font.lua @@ -0,0 +1,73 @@ +-- ### Nerd fonts + +-- DESCRIPTION: +-- Here you can edit the icons displayed in NormalNvim. + +-- If you can't see the default icons: +-- Install nerd fonts and set it as your terminal font: +-- https://www.nerdfonts.com/ + +return { + ActiveLSP = "", + ActiveTS = "", + ArrowLeft = "", + ArrowRight = "", + Bookmarks = "", + BufferClose = "󰅖", + DapBreakpoint = "", + DapBreakpointCondition = "", + DapBreakpointRejected = "", + DapLogPoint = ".>", + DapStopped = "󰁕", + Debugger = "", + DefaultFile = "󰈙", + Diagnostic = "󰒡", + DiagnosticError = "", + DiagnosticHint = "󰌵", + DiagnosticInfo = "󰋼", + DiagnosticWarn = "", + Ellipsis = "…", + Environment = "", + FileNew = "", + FileModified = "", + FileReadOnly = "", + FoldClosed = "", + FoldOpened = "", + FoldSeparator = " ", + FolderClosed = "", + FolderEmpty = "", + FolderOpen = "", + Git = "󰊢", + GitAdd = "", + GitBranch = "", + GitChange = "", + GitConflict = "", + GitDelete = "", + GitIgnored = "◌", + GitRenamed = "➜", + GitSign = "▎", + GitStaged = "✓", + GitUnstaged = "✗", + GitUntracked = "★", + LSPLoaded = "", + LSPLoading1 = "", + LSPLoading2 = "󰀚", + LSPLoading3 = "", + MacroRecording = "", + Package = "󰏖", + Paste = "󰅌", + Refresh = "", + Run = "󰑮", + Search = "", + Selected = "❯", + Session = "󱂬", + Sort = "󰒺", + Spellcheck = "󰓆", + Tab = "󰓩", + TabClose = "󰅙", + Terminal = "", + Window = "", + WordFile = "󰈭", + Test = "󰙨", + Docs = "", +} diff --git a/dot_config/nvim/lua/base/icons/text.lua b/dot_config/nvim/lua/base/icons/text.lua new file mode 100644 index 0000000000000000000000000000000000000000..70fc839dbbff775abf1e674f4f947e5b69b8c5b1 --- /dev/null +++ b/dot_config/nvim/lua/base/icons/text.lua @@ -0,0 +1,48 @@ +-- ### Text fonts + +-- DESCRIPTION: +-- Fallback icons that will be displayed +-- if you don't have nerd fonts installed, +-- or if you set `vim.g.icons_enabled = false` on `../1-options.lua`. + +return { + ActiveLSP = "LSP:", + ArrowLeft = "<", + ArrowRight = ">", + BufferClose = "x", + DapBreakpoint = "B", + DapBreakpointCondition = "C", + DapBreakpointRejected = "R", + DapLogPoint = "L", + DapStopped = ">", + DefaultFile = "[F]", + DiagnosticError = "X", + DiagnosticHint = "?", + DiagnosticInfo = "i", + DiagnosticWarn = "!", + Ellipsis = "...", + Environment = "Env:", + FileModified = "*", + FileReadOnly = "[lock]", + FoldClosed = "+", + FoldOpened = "-", + FoldSeparator = " ", + FolderClosed = "[D]", + FolderEmpty = "[E]", + FolderOpen = "[O]", + GitAdd = "[+]", + GitChange = "[/]", + GitConflict = "[!]", + GitDelete = "[-]", + GitIgnored = "[I]", + GitRenamed = "[R]", + GitStaged = "[S]", + GitUnstaged = "[U]", + GitUntracked = "[?]", + MacroRecording = "Recording:", + Paste = "[PASTE]", + Search = "?", + Selected = "*", + Spellcheck = "[SPELL]", + TabClose = "X", +} diff --git a/dot_config/nvim/lua/base/utils/init.lua b/dot_config/nvim/lua/base/utils/init.lua new file mode 100644 index 0000000000000000000000000000000000000000..50d696e5c4fbf3b6e0c8063ff1b2826773eada24 --- /dev/null +++ b/dot_config/nvim/lua/base/utils/init.lua @@ -0,0 +1,307 @@ +--- ### General utils. +-- +-- DESCRIPTION: +-- General utility functions to use within Nvim. + +-- Functions: +-- -> run_cmd → Run a shell command and return true/false. +-- -> add_autocmds_to_buffer → Add autocmds to a bufnr. +-- -> del_autocmds_from_buffer → Delete autocmds from a bufnr. +-- -> get_icon → Return an icon from the icons directory. +-- -> get_mappings_template → Return a empty mappings table. +-- -> is_available → Return true if the plugin exist. +-- -> is_big_file → Return true if the file is too big. +-- -> notify → Send a notification with a default title. +-- -> os_path → Converts a path to the current OS. +-- -> get_plugin_opts → Return a plugin opts table. +-- -> set_mappings → Set a list of mappings in a clean way. +-- -> set_url_effect → Show an effect for urls. +-- -> open_with_program → Open the file or URL under the cursor. +-- -> trigger_event → Manually trigger a event. +-- -> which_key_register → When setting a mapping, add it to whichkey. + + +local M = {} + +--- Run a shell command and capture the output and if the command +--- succeeded or failed. +---@param cmd string|string[] The terminal command to execute +---@param show_error? boolean If true, print errors if the command fail. +---@return string|nil # The result of a successfully executed command or nil +function M.run_cmd(cmd, show_error) + if type(cmd) == "string" then cmd = vim.split(cmd, " ") end + if vim.fn.has "win32" == 1 then cmd = vim.list_extend({ "cmd.exe", "/C" }, cmd) end + local result = vim.fn.system(cmd) + local success = vim.api.nvim_get_vvar "shell_error" == 0 + if not success and (show_error == nil or show_error) then + vim.api.nvim_err_writeln(("Error running command %s\nError message:\n%s"):format(table.concat(cmd, " "), result)) + end + return success and result:gsub("[\27\155][][()#;?%d]*[A-PRZcf-ntqry=><~]", "") or nil +end + +--- Adds autocmds to a specific buffer if they don't already exist. +--- +--- @param augroup string The name of the autocmd group to which the autocmds belong. +--- @param bufnr number The buffer number to which the autocmds should be applied. +--- @param autocmds table|any A table or a single autocmd definition containing the autocmds to add. +function M.add_autocmds_to_buffer(augroup, bufnr, autocmds) + -- Check if autocmds is a list, if not convert it to a list + if not vim.islist(autocmds) then autocmds = { autocmds } end + + -- Attempt to retrieve existing autocmds associated with the specified augroup and bufnr + local cmds_found, cmds = pcall(vim.api.nvim_get_autocmds, { group = augroup, buffer = bufnr }) + + -- If no existing autocmds are found or the cmds_found call fails + if not cmds_found or vim.tbl_isempty(cmds) then + -- Create a new augroup if it doesn't already exist + vim.api.nvim_create_augroup(augroup, { clear = false }) + + -- Iterate over each autocmd provided + for _, autocmd in ipairs(autocmds) do + -- Extract the events from the autocmd and remove the events key + local events = autocmd.events + autocmd.events = nil + + -- Set the group and buffer keys for the autocmd + autocmd.group = augroup + autocmd.buffer = bufnr + + -- Create the autocmd + vim.api.nvim_create_autocmd(events, autocmd) + end + end +end + +--- Deletes autocmds associated with a specific buffer and autocmd group. +--- +--- @param augroup string The name of the autocmd group from which the autocmds should be removed. +--- @param bufnr number The buffer number from which the autocmds should be removed. +function M.del_autocmds_from_buffer(augroup, bufnr) + -- Attempt to retrieve existing autocmds associated with the specified augroup and bufnr + local cmds_found, cmds = pcall(vim.api.nvim_get_autocmds, { group = augroup, buffer = bufnr }) + + -- If retrieval was successful + if cmds_found then + -- Map over each retrieved autocmd and delete it + vim.tbl_map(function(cmd) vim.api.nvim_del_autocmd(cmd.id) end, cmds) + end +end + +--- Get an icon from `lspkind` if it is available and return it. +---@param kind string The kind of icon in `lspkind` to retrieve. +---@return string icon. +function M.get_icon(kind, padding, no_fallback) + if not vim.g.icons_enabled and no_fallback then return "" end + local icon_pack = vim.g.icons_enabled and "icons" or "text_icons" + if not M[icon_pack] then + M.icons = require("base.icons.nerd_font") + M.text_icons = require("base.icons.text") + end + local icon = M[icon_pack] and M[icon_pack][kind] + return icon and icon .. string.rep(" ", padding or 0) or "" +end + +--- Get an empty table of mappings with a key for each map mode. +---@return table # a table with entries for each map mode. +function M.get_mappings_template() + local maps = {} + for _, mode in ipairs { "", "n", "v", "x", "s", "o", "!", "i", "l", "c", "t" } do + maps[mode] = {} + end + if vim.fn.has "nvim-0.10.0" == 1 then + for _, abbr_mode in ipairs { "ia", "ca", "!a" } do + maps[abbr_mode] = {} + end + end + return maps +end + +--- Check if a plugin is defined in lazy. Useful with lazy loading +--- when a plugin is not necessarily loaded yet. +---@param plugin string The plugin to search for. +---@return boolean available # Whether the plugin is available. +function M.is_available(plugin) + local lazy_config_avail, lazy_config = pcall(require, "lazy.core.config") + return lazy_config_avail and lazy_config.spec.plugins[plugin] ~= nil +end + +--- Returns true if the file is considered a big file, +--- according to the criteria defined in `vim.g.big_file`. +---@param bufnr number|nil buffer number. 0 by default, which means current buf. +---@return boolean is_big_file true or false. +function M.is_big_file(bufnr) + if bufnr == nil then bufnr = 0 end + local filesize = vim.fn.getfsize(vim.api.nvim_buf_get_name(bufnr)) + local nlines = vim.api.nvim_buf_line_count(bufnr) + local is_big_file = (filesize > vim.g.big_file.size) + or (nlines > vim.g.big_file.lines) + return is_big_file +end + +--- Sends a notification with 'Neovim' as default title. +--- Same as using vim.notify, but it saves us typing the title every time. +---@param msg string The notification body. +---@param type number|nil The type of the notification (:help vim.log.levels). +---@param opts? table The nvim-notify options to use (:help notify-options). +function M.notify(msg, type, opts) + vim.schedule(function() + vim.notify( + msg, type, vim.tbl_deep_extend("force", { title = "Neovim" }, opts or {})) + end) +end + +--- Convert a path to the path format of the current operative system. +--- It converts 'slash' to 'inverted slash' if on windows, and vice versa on UNIX. +---@param path string A path string. +---@return string|nil,nil path A path string formatted for the current OS. +function M.os_path(path) + if path == nil then return nil end + -- Get the platform-specific path separator + local separator = string.sub(package.config, 1, 1) + return string.gsub(path, '[/\\]', separator) +end + +--- Get the options of a plugin managed by lazy. +---@param plugin string The plugin to get options from +---@return table opts # The plugin options, or empty table if no plugin. +function M.get_plugin_opts(plugin) + local lazy_config_avail, lazy_config = pcall(require, "lazy.core.config") + local lazy_plugin_avail, lazy_plugin = pcall(require, "lazy.core.plugin") + local opts = {} + if lazy_config_avail and lazy_plugin_avail then + local spec = lazy_config.spec.plugins[plugin] + if spec then opts = lazy_plugin.values(spec, "opts") end + end + return opts +end + +--- Set a table of mappings. +--- +--- This wrapper prevents a boilerplate code, and takes care of `whichkey.nvim`. +---@param map_table table A nested table where the first key is the vim mode, +--- the second key is the key to map, and the value is +--- the function to set the mapping to. +---@param base? table A base set of options to set on every keybinding. +function M.set_mappings(map_table, base) + -- iterate over the first keys for each mode + base = base or {} + for mode, maps in pairs(map_table) do + -- iterate over each keybinding set in the current mode + for keymap, options in pairs(maps) do + -- build the options for the command accordingly + if options then + local cmd = options + local keymap_opts = base + if type(options) == "table" then + cmd = options[1] + keymap_opts = vim.tbl_deep_extend("force", keymap_opts, options) + keymap_opts[1] = nil + end + if not cmd or keymap_opts.name then -- if which-key mapping, queue it + if not keymap_opts.name then keymap_opts.name = keymap_opts.desc end + if not M.which_key_queue then M.which_key_queue = {} end + if not M.which_key_queue[mode] then M.which_key_queue[mode] = {} end + M.which_key_queue[mode][keymap] = keymap_opts + else -- if not which-key mapping, set it + vim.keymap.set(mode, keymap, cmd, keymap_opts) + end + end + end + end + -- if which-key is loaded already, register + if package.loaded["which-key"] then M.which_key_register() end +end + +--- Add syntax matching rules for highlighting URLs/URIs. +function M.set_url_effect() + --- regex used for matching a valid URL/URI string + local url_matcher = + "\\v\\c%(%(h?ttps?|ftp|file|ssh|git)://|[a-z]+[@][a-z]+[.][a-z]+:)" .. + "%([&:#*@~%_\\-=?!+;/0-9a-z]+%(%([.;/?]|[.][.]+)" .. + "[&:#*@~%_\\-=?!+/0-9a-z]+|:\\d+|,%(%(%(h?ttps?|ftp|file|ssh|git)://|" .. + "[a-z]+[@][a-z]+[.][a-z]+:)@![0-9a-z]+))*|\\([&:#*@~%_\\-=?!+;/.0-9a-z]*\\)" .. + "|\\[[&:#*@~%_\\-=?!+;/.0-9a-z]*\\]|\\{%([&:#*@~%_\\-=?!+;/.0-9a-z]*" .. + "|\\{[&:#*@~%_\\-=?!+;/.0-9a-z]*})\\})+" + + M.delete_url_effect() + if vim.g.url_effect_enabled then + vim.fn.matchadd("HighlightURL", url_matcher, 15) + end +end + +--- Delete the syntax matching rules for URLs/URIs if set. +function M.delete_url_effect() + for _, match in ipairs(vim.fn.getmatches()) do + if match.group == "HighlightURL" then vim.fn.matchdelete(match.id) end + end +end + +--- Open the file or url under the cursor. +---@param path string The path of the file to open with the system opener. +function M.open_with_program(path) + if vim.ui.open then return vim.ui.open(path) end + local cmd + if vim.fn.has "mac" == 1 then + cmd = { "open" } + elseif vim.fn.has "win32" == 1 then + if vim.fn.executable "rundll32" then + cmd = { "rundll32", "url.dll,FileProtocolHandler" } + else + cmd = { "cmd.exe", "/K", "explorer" } + end + elseif vim.fn.has "unix" == 1 then + if vim.fn.executable "explorer.exe" == 1 then -- available in WSL + cmd = { "explorer.exe" } + elseif vim.fn.executable "xdg-open" == 1 then + cmd = { "xdg-open" } + end + end + if not cmd then M.notify("Available system opening tool not found!", vim.log.levels.ERROR) end + if not path then + path = vim.fn.expand "" + elseif not path:match "%w+:" then + path = vim.fn.expand(path) + end + vim.fn.jobstart(vim.list_extend(cmd, { path }), { detach = true }) +end + +--- Convenient wapper to save code when we Trigger events. +--- To listen for a event triggered by this function you can use `autocmd`. +---@param event string Name of the event. +---@param is_urgent boolean|nil If true, trigger directly instead of scheduling. Useful for startup events. +-- @usage To run a User event: `trigger_event("User MyUserEvent")` +-- @usage To run a Neovim event: `trigger_event("BufEnter") +function M.trigger_event(event, is_urgent) + -- define behavior + local function trigger() + local is_user_event = string.match(event, "^User ") ~= nil + if is_user_event then + event = event:gsub("^User ", "") + vim.api.nvim_exec_autocmds("User", { pattern = event, modeline = false }) + else + vim.api.nvim_exec_autocmds(event, { modeline = false }) + end + end + + -- execute + if is_urgent then + trigger() + else + vim.schedule(trigger) + end +end + +--- Register queued which-key mappings. +function M.which_key_register() + if M.which_key_queue then + local wk_avail, wk = pcall(require, "which-key") + if wk_avail then + for mode, registration in pairs(M.which_key_queue) do + wk.register(registration, { mode = mode }) + end + M.which_key_queue = nil + end + end +end + +return M diff --git a/dot_config/nvim/lua/base/utils/lsp.lua b/dot_config/nvim/lua/base/utils/lsp.lua new file mode 100644 index 0000000000000000000000000000000000000000..efc2f54d8311f36df426cfbfbb1cd0ee188023fd --- /dev/null +++ b/dot_config/nvim/lua/base/utils/lsp.lua @@ -0,0 +1,189 @@ +--- ### LSP utils. +-- +-- DESCRIPTION: +-- Functions we use to configure the plugin `mason-lspconfig.nvim`. +-- You can specify your own lsp settings inside `M.apply_user_lsp_settings()`. +-- +-- Most options we use in `M.apply_default_lsp_settings()` +-- can be tweaked on the file `../1-options.lua`. +-- Take this into consideration to minimize the risk of breaking stuff. + +-- Functions: +-- -> M.apply_default_lsp_settings → Apply our default lsp settings. +-- -> M.apply_user_lsp_mappings → Apply the user lsp keymappings. +-- -> M.apply_user_lsp_settings → Apply the user lsp settings. +-- -> M.setup → It passes the user lsp settings to lspconfig. + +local M = {} +local utils = require "base.utils" +local stored_handlers = {} + +--- Apply default settings for diagnostics, formatting, and lsp capabilities. +--- It only need to be executed once, normally on mason-lspconfig. +---@return nil +M.apply_default_lsp_settings = function() + -- Icons + -- Apply the icons defined in ../icons/nerd_font.lua + local get_icon = utils.get_icon + local signs = { + { name = "DiagnosticSignError", text = get_icon("DiagnosticError"), texthl = "DiagnosticSignError" }, + { name = "DiagnosticSignWarn", text = get_icon("DiagnosticWarn"), texthl = "DiagnosticSignWarn" }, + { name = "DiagnosticSignHint", text = get_icon("DiagnosticHint"), texthl = "DiagnosticSignHint" }, + { name = "DiagnosticSignInfo", text = get_icon("DiagnosticInfo"), texthl = "DiagnosticSignInfo" }, + { name = "DapStopped", text = get_icon("DapStopped"), texthl = "DiagnosticWarn" }, + { name = "DapBreakpoint", text = get_icon("DapBreakpoint"), texthl = "DiagnosticInfo" }, + { name = "DapBreakpointRejected", text = get_icon("DapBreakpointRejected"), texthl = "DiagnosticError" }, + { name = "DapBreakpointCondition", text = get_icon("DapBreakpointCondition"), texthl = "DiagnosticInfo" }, + { name = "DapLogPoint", text = get_icon("DapLogPoint"), texthl = "DiagnosticInfo" } + } + for _, sign in ipairs(signs) do + vim.fn.sign_define(sign.name, sign) + end + + -- Borders + -- Apply the option lsp_round_borders_enabled from ../1-options.lua + if vim.g.lsp_round_borders_enabled then + vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { border = "rounded", silent = true }) + vim.lsp.handlers["textDocument/signatureHelp"] = + vim.lsp.with(vim.lsp.handlers.signature_help, { border = "rounded", silent = true }) + end + + -- Set default diagnostics + local default_diagnostics = { + virtual_text = true, + signs = { + text = { + [vim.diagnostic.severity.ERROR] = utils.get_icon("DiagnosticError"), + [vim.diagnostic.severity.HINT] = utils.get_icon("DiagnosticHint"), + [vim.diagnostic.severity.WARN] = utils.get_icon("DiagnosticWarn"), + [vim.diagnostic.severity.INFO] = utils.get_icon("DiagnosticInfo"), + }, + active = signs, + }, + update_in_insert = true, + underline = true, + severity_sort = true, + float = { + focused = false, + style = "minimal", + border = "rounded", + source = "always", + header = "", + prefix = "", + }, + } + + -- Apply default diagnostics + -- Applies the option diagnostics_mode from ../1-options.lua + M.diagnostics = { + -- diagnostics off + [0] = vim.tbl_deep_extend( + "force", + default_diagnostics, + { underline = false, virtual_text = false, signs = false, update_in_insert = false } + ), + -- status only + vim.tbl_deep_extend("force", default_diagnostics, { virtual_text = false, signs = false }), + -- virtual text off, signs on + vim.tbl_deep_extend("force", default_diagnostics, { virtual_text = false }), + -- all diagnostics on + default_diagnostics, + } + vim.diagnostic.config(M.diagnostics[vim.g.diagnostics_mode]) + + -- Apply formatting settings + M.formatting = { format_on_save = { enabled = true }, disabled = {} } + if type(M.formatting.format_on_save) == "boolean" then + M.formatting.format_on_save = { enabled = M.formatting.format_on_save } + end + M.format_opts = vim.deepcopy(M.formatting) + M.format_opts.disabled = nil + M.format_opts.format_on_save = nil + M.format_opts.filter = function(client) + local filter = M.formatting.filter + local disabled = M.formatting.disabled or {} + -- check if client is fully disabled or filtered by function + return not (vim.tbl_contains(disabled, client.name) or (type(filter) == "function" and not filter(client))) + end +end + +--- This function has the sole purpose of passing the lsp keymappings to lsp. +--- We have this function, because we use it on none-ls. +---@param client string The client where the lsp mappings will load. +---@param bufnr string The bufnr where the lsp mappings will load. +function M.apply_user_lsp_mappings(client, bufnr) + local lsp_mappings = require("base.4-mappings").lsp_mappings(client, bufnr) + if not vim.tbl_isempty(lsp_mappings.v) then + lsp_mappings.v["l"] = { desc = utils.get_icon("ActiveLSP", 1, true) .. "LSP" } + end + utils.set_mappings(lsp_mappings, { buffer = bufnr }) +end + +--- Here you can specify custom settings for the lsp servers you install. +--- This is not normally necessary. But you can. +---@param server_name string The name of the server +---@return table # The table of LSP options used when setting up the given language server +function M.apply_user_lsp_settings(server_name) + local server = require("lspconfig")[server_name] + + -- Define user server capabilities. + M.capabilities = vim.lsp.protocol.make_client_capabilities() + M.capabilities.textDocument.completion.completionItem.documentationFormat = { "markdown", "plaintext" } + M.capabilities.textDocument.completion.completionItem.snippetSupport = true + M.capabilities.textDocument.completion.completionItem.preselectSupport = true + M.capabilities.textDocument.completion.completionItem.insertReplaceSupport = true + M.capabilities.textDocument.completion.completionItem.labelDetailsSupport = true + M.capabilities.textDocument.completion.completionItem.deprecatedSupport = true + M.capabilities.textDocument.completion.completionItem.commitCharactersSupport = true + M.capabilities.textDocument.completion.completionItem.tagSupport = { valueSet = { 1 } } + M.capabilities.textDocument.completion.completionItem.resolveSupport = + { properties = { "documentation", "detail", "additionalTextEdits" } } + M.capabilities.textDocument.foldingRange = { dynamicRegistration = false, lineFoldingOnly = true } + M.flags = {} + local opts = vim.tbl_deep_extend("force", server, { capabilities = M.capabilities, flags = M.flags }) + + -- Define user server rules. + if server_name == "jsonls" then -- Add schemastore schemas + local is_schemastore_loaded, schemastore = pcall(require, "schemastore") + if is_schemastore_loaded then + opts.settings = { json = { schemas = schemastore.json.schemas(), validate = { enable = true } } } + end + end + if server_name == "yamlls" then -- Add schemastore schemas + local is_schemastore_loaded, schemastore = pcall(require, "schemastore") + if is_schemastore_loaded then opts.settings = { yaml = { schemas = schemastore.yaml.schemas() } } end + end + if server_name == "lua_ls" then -- Disable third party checking + pcall(require, "neodev") + opts.settings = { Lua = { workspace = { checkThirdParty = false } } } + end + + -- Apply them + local old_on_attach = server.on_attach + opts.on_attach = function(client, bufnr) + -- If the server on_attach function exist → server.on_attach(client, bufnr) + if type(old_on_attach) == "function" then old_on_attach(client, bufnr) end + -- Also, apply mappings to the buffer. + M.apply_user_lsp_mappings(client, bufnr) + end + return opts +end + +--- This function passes the `user lsp settings` to lspconfig, +--- which is the responsible of configuring everything for us. +--- +--- You are meant to call this function from the plugin `mason-lspconfig.nvim`. +---@param server string A lsp server name. +---@return nil +M.setup = function(server) + -- Get the user settings. + local opts = M.apply_user_lsp_settings(server) + + -- Get a handler from lspconfig. + local setup_handler = stored_handlers[server] or require("lspconfig")[server].setup(opts) + + -- Apply our user settings to the lspconfig handler. + if setup_handler then setup_handler(server, opts) end +end + +return M diff --git a/dot_config/nvim/lua/base/utils/ui.lua b/dot_config/nvim/lua/base/utils/ui.lua new file mode 100644 index 0000000000000000000000000000000000000000..f7bc50ebeab70db04acb078f68ebb6d792e42bb7 --- /dev/null +++ b/dot_config/nvim/lua/base/utils/ui.lua @@ -0,0 +1,321 @@ +--- ### UI toggle functions. +-- +-- DESCRIPTION: +-- While you could technically delete this file, we encourage you +-- to keep it as it takes a lot of complexity out of `../4-mappings.lua`. + +-- Functions: +-- -> change_number +-- -> set_indent +-- -> toggle_animations +-- -> toggle_autoformat +-- -> toggle_autopairs +-- -> toggle_background +-- -> toggle_buffer_autoformat +-- -> toggle_buffer_inlay_hints +-- -> toggle_buffer_semantic_tokens +-- -> toggle_buffer_syntax +-- -> toggle_codelens +-- -> toggle_coverage_signs +-- -> toggle_cmp +-- -> toggle_conceal +-- -> toggle_diagnostics +-- -> toggle_foldcolumn +-- -> toggle_inlay_hints +-- -> toggle_lsp_signature +-- -> toggle_paste +-- -> toggle_signcolumn +-- -> toggle_spell +-- -> toggle_statusline +-- -> toggle_tabline +-- -> toggle_ui_notifications +-- -> toggle_url_effect +-- -> toggle_wrap +-- -> toggle_zen_mode + + +local M = {} +local utils = require("base.utils") +local function bool2str(bool) return bool and "on" or "off" end + +--- Change the number display modes +function M.change_number() + local number = vim.wo.number -- local to window + local relativenumber = vim.wo.relativenumber -- local to window + if not number and not relativenumber then + vim.wo.number = true + elseif number and not relativenumber then + vim.wo.relativenumber = true + elseif number and relativenumber then + vim.wo.number = false + else -- not number and relativenumber + vim.wo.relativenumber = false + end + utils.notify(string.format("number %s, relativenumber %s", bool2str(vim.wo.number), bool2str(vim.wo.relativenumber))) +end + +--- Set the indent and tab related numbers +function M.set_indent() + local input_avail, input = pcall(vim.fn.input, "Set indent value (>0 expandtab, <=0 noexpandtab): ") + if input_avail then + local indent = tonumber(input) + if not indent or indent == 0 then return end + vim.bo.expandtab = (indent > 0) -- local to buffer + indent = math.abs(indent) + vim.bo.tabstop = indent -- local to buffer + vim.bo.softtabstop = indent -- local to buffer + vim.bo.shiftwidth = indent -- local to buffer + utils.notify(string.format("indent=%d %s", indent, vim.bo.expandtab and "expandtab" or "noexpandtab")) + end +end + +--- Toggle animations +function M.toggle_animations() + if vim.g.minianimate_disable then + vim.g.minianimate_disable = false + else + vim.g.minianimate_disable = true + end + + local state = vim.g.minianimate_disable + utils.notify(string.format("animations %s", bool2str(not state))) +end + +--- Toggle auto format +function M.toggle_autoformat() + vim.g.autoformat_enabled = not vim.g.autoformat_enabled + utils.notify(string.format("Global autoformatting %s", bool2str(vim.g.autoformat_enabled))) +end + +--- Toggle autopairs +function M.toggle_autopairs() + local ok, autopairs = pcall(require, "nvim-autopairs") + if ok then + if autopairs.state.disabled then + autopairs.enable() + else + autopairs.disable() + end + vim.g.autopairs_enabled = autopairs.state.disabled + utils.notify(string.format("autopairs %s", bool2str(not autopairs.state.disabled))) + else + utils.notify "autopairs not available" + end +end + +--- Toggle background="dark"|"light" +function M.toggle_background() + vim.go.background = vim.go.background == "light" and "dark" or "light" + utils.notify(string.format("background=%s", vim.go.background)) +end + +--- Toggle buffer local auto format +function M.toggle_buffer_autoformat(bufnr) + bufnr = bufnr or 0 + local old_val = vim.b[bufnr].autoformat_enabled + if old_val == nil then old_val = vim.g.autoformat_enabled end + vim.b[bufnr].autoformat_enabled = not old_val + utils.notify(string.format("Buffer autoformatting %s", bool2str(vim.b[bufnr].autoformat_enabled))) +end + +--- Toggle LSP inlay hints (buffer) +-- @param bufnr? number the buffer to toggle the clients on +function M.toggle_buffer_inlay_hints(bufnr) + bufnr = bufnr or 0 + vim.b[bufnr].inlay_hints_enabled = not vim.b[bufnr].inlay_hints_enabled + vim.lsp.inlay_hint.enable(vim.b[bufnr].inlay_hints_enabled, { bufnr = bufnr }) + utils.notify(string.format("Buffer inlay hints %s", bool2str(vim.b[bufnr].inlay_hints_enabled))) +end + +--- Toggle buffer semantic token highlighting for all language servers that support it +--@param bufnr? number the buffer to toggle the clients on +function M.toggle_buffer_semantic_tokens(bufnr) + bufnr = bufnr or 0 + vim.b[bufnr].semantic_tokens_enabled = not vim.b[bufnr].semantic_tokens_enabled + for _, client in ipairs(vim.lsp.get_clients({ bufnr = bufnr })) do + if client.server_capabilities.semanticTokensProvider then + vim.lsp.semantic_tokens[vim.b[bufnr].semantic_tokens_enabled and "start" or "stop"](bufnr, client.id) + utils.notify(string.format("Buffer lsp semantic highlighting %s", bool2str(vim.b[bufnr].semantic_tokens_enabled))) + end + end +end + +--- Toggle syntax highlighting and treesitter +function M.toggle_buffer_syntax(bufnr) + -- HACK: this should just be `bufnr = bufnr or 0` but it looks like + -- `vim.treesitter.stop` has a bug with `0` being current. + bufnr = (bufnr and bufnr ~= 0) and bufnr or vim.api.nvim_win_get_buf(0) + local ts_avail, parsers = pcall(require, "nvim-treesitter.parsers") + if vim.bo[bufnr].syntax == "off" then + if ts_avail and parsers.has_parser() then vim.treesitter.start(bufnr) end + vim.bo[bufnr].syntax = "on" + if not vim.b.semantic_tokens_enabled then M.toggle_buffer_semantic_tokens(bufnr, true) end + else + if ts_avail and parsers.has_parser() then vim.treesitter.stop(bufnr) end + vim.bo[bufnr].syntax = "off" + if vim.b.semantic_tokens_enabled then M.toggle_buffer_semantic_tokens(bufnr, true) end + end + utils.notify(string.format("syntax %s", bool2str(vim.bo[bufnr].syntax))) +end + +--- Toggle codelens +function M.toggle_codelens(bufnr) + bufnr = bufnr or 0 + vim.g.codelens_enabled = not vim.g.codelens_enabled + if vim.g.codelens_enabled then + vim.lsp.codelens.refresh({ bufnr = bufnr }) + else + vim.lsp.codelens.clear() + end + utils.notify(string.format("CodeLens %s", bool2str(vim.g.codelens_enabled))) +end + +--- Toggle coverage signs +function M.toggle_coverage_signs(bufnr) + bufnr = bufnr or 0 + vim.b[bufnr].coverage_signs_enabled = not vim.b[bufnr].coverage_signs_enabled + if vim.b[bufnr].coverage_signs_enabled then + utils.notify("Coverage signs on:" .. + "\n\n- Git signs will be temporary disabled." .. + "\n- Diagnostic signs won't be automatically disabled.") + vim.cmd("Gitsigns toggle_signs") + require("coverage").load(true) + else + utils.notify("Coverage signs off:\n\n- Git signs re-enabled.") + require("coverage").hide() + vim.cmd("Gitsigns toggle_signs") + end +end + +--- Toggle cmp entrirely +function M.toggle_cmp() + vim.g.cmp_enabled = not vim.g.cmp_enabled + local ok, _ = pcall(require, "cmp") + utils.notify(ok and string.format("completion %s", bool2str(vim.g.cmp_enabled)) or "completion not available") +end + +--- Toggle conceal=2|0 +function M.toggle_conceal() + vim.opt.conceallevel = vim.opt.conceallevel:get() == 0 and 2 or 0 + utils.notify(string.format("conceal %s", bool2str(vim.opt.conceallevel:get() == 2))) +end + +--- Toggle diagnostics +function M.toggle_diagnostics() + vim.g.diagnostics_mode = (vim.g.diagnostics_mode - 1) % 4 + vim.diagnostic.config(require("base.utils.lsp").diagnostics[vim.g.diagnostics_mode]) + if vim.g.diagnostics_mode == 0 then + utils.notify "diagnostics off" + elseif vim.g.diagnostics_mode == 1 then + utils.notify "only status diagnostics" + elseif vim.g.diagnostics_mode == 2 then + utils.notify "virtual text off" + else + utils.notify "all diagnostics on" + end +end + +local last_active_foldcolumn +--- Toggle foldcolumn=0|1 +function M.toggle_foldcolumn() + local curr_foldcolumn = vim.wo.foldcolumn + if curr_foldcolumn ~= "0" then last_active_foldcolumn = curr_foldcolumn end + vim.wo.foldcolumn = curr_foldcolumn == "0" and (last_active_foldcolumn or "1") or "0" + utils.notify(string.format("foldcolumn=%s", vim.wo.foldcolumn)) +end + +--- Toggle LSP inlay hints (global) +-- @param bufnr? number the buffer to toggle the clients on +function M.toggle_inlay_hints(bufnr) + bufnr = bufnr or 0 + vim.g.inlay_hints_enabled = not vim.g.inlay_hints_enabled -- flip global state + vim.b.inlay_hints_enabled = not vim.g.inlay_hints_enabled -- sync buffer state + vim.lsp.buf.inlay_hint.enable(vim.g.inlay_hints_enabled, { bufnr = bufnr }) -- apply state + utils.notify(string.format("Global inlay hints %s", bool2str(vim.g.inlay_hints_enabled))) +end + +--- Toggle lsp signature +function M.toggle_lsp_signature() + local state = require('lsp_signature').toggle_float_win() + utils.notify(string.format("lsp signature %s", bool2str(state))) +end + +--- Toggle paste +function M.toggle_paste() + vim.opt.paste = not vim.opt.paste:get() -- local to window + utils.notify(string.format("paste %s", bool2str(vim.opt.paste:get()))) +end + +--- Toggle signcolumn="auto"|"no" +function M.toggle_signcolumn() + if vim.wo.signcolumn == "no" then + vim.wo.signcolumn = "yes" + elseif vim.wo.signcolumn == "yes" then + vim.wo.signcolumn = "auto" + else + vim.wo.signcolumn = "no" + end + utils.notify(string.format("signcolumn=%s", vim.wo.signcolumn)) +end + +--- Toggle spell +function M.toggle_spell() + vim.wo.spell = not vim.wo.spell -- local to window + utils.notify(string.format("spell %s", bool2str(vim.wo.spell))) +end + +--- Toggle laststatus=3|2|0 +function M.toggle_statusline() + local laststatus = vim.opt.laststatus:get() + local status + if laststatus == 0 then + vim.opt.laststatus = 2 + status = "local" + elseif laststatus == 2 then + vim.opt.laststatus = 3 + status = "global" + elseif laststatus == 3 then + vim.opt.laststatus = 0 + status = "off" + end + utils.notify(string.format("statusline %s", status)) +end + +--- Toggle showtabline=2|0 +function M.toggle_tabline() + vim.opt.showtabline = vim.opt.showtabline:get() == 0 and 2 or 0 + utils.notify(string.format("tabline %s", bool2str(vim.opt.showtabline:get() == 2))) +end + +--- Toggle notifications for UI toggles +function M.toggle_ui_notifications() + vim.g.notifications_enabled = not vim.g.notifications_enabled + utils.notify(string.format("Notifications %s", bool2str(vim.g.notifications_enabled))) +end + +--- Toggle URL/URI syntax highlighting rules +function M.toggle_url_effect() + vim.g.url_effect_enabled = not vim.g.url_effect_enabled + require("base.utils").set_url_effect() + utils.notify(string.format("URL effect %s", bool2str(vim.g.url_effect_enabled))) +end + +--- Toggle wrap +function M.toggle_wrap() + vim.wo.wrap = not vim.wo.wrap -- local to window + utils.notify(string.format("wrap %s", bool2str(vim.wo.wrap))) +end + +--- Toggle zen mode +function M.toggle_zen_mode(bufnr) + bufnr = bufnr or 0 + if not vim.b[bufnr].zen_mode then + vim.b[bufnr].zen_mode = true + else + vim.b[bufnr].zen_mode = false + end + utils.notify(string.format("zen mode %s", bool2str(vim.b[bufnr].zen_mode))) + vim.cmd "ZenMode" +end + +return M diff --git a/dot_config/nvim/lua/plugins/1-base-behaviors.lua b/dot_config/nvim/lua/plugins/1-base-behaviors.lua new file mode 100644 index 0000000000000000000000000000000000000000..6c3c4cdae9a0891b4a1f927939eb3813d3c66793 --- /dev/null +++ b/dot_config/nvim/lua/plugins/1-base-behaviors.lua @@ -0,0 +1,709 @@ +-- Core behaviors +-- Things that add new behaviors. + +-- Sections: +-- -> ranger file browser [ranger] +-- -> project.nvim [project search + auto cd] +-- -> trim.nvim [auto trim spaces] +-- -> stickybuf.nvim [lock special buffers] +-- -> mini.bufremove [smart bufdelete] +-- -> smart-splits [move and resize buffers] +-- -> better-scape.nvim [esc] +-- -> toggleterm.nvim [term] +-- -> session-manager [session] +-- -> spectre.nvim [search and replace in project] +-- -> neotree file browser [neotree] +-- -> nvim-ufo [folding mod] +-- -> nvim-neoclip [nvim clipboard] +-- -> zen-mode.nvim [distraction free mode] +-- -> suda.vim [write as sudo] +-- -> vim-matchup [Improved % motion] +-- -> hop.nvim [go to word visually] +-- -> nvim-autopairs [auto close brackets] +-- -> lsp_signature.nvim [auto params help] +-- -> nvim-lightbulb [lightbulb for code actions] +-- -> distroupdate.nvim [distro update] + +local is_windows = vim.fn.has('win32') == 1 -- true if on windows +local is_android = vim.fn.isdirectory('/data') == 1 -- true if on android + +return { + -- [ranger] file browser + -- https://github.com/kevinhwang91/rnvimr + -- This is NormalNvim file browser, which is only for Linux. + -- + -- If you are on Windows, you have 3 options: + -- * Use neotree instead (+e). + -- * Delete rnvimr and install some other file browser you like. + -- * Or enable WLS on Windows and launch neovim from there. + -- This way you can install and use 'ranger' and its dependency 'pynvim'. + { + "kevinhwang91/rnvimr", + event = "User BaseDefered", + cmd = { "RnvimrToggle" }, + enabled = not is_windows, + config = function() + -- vim.g.rnvimr_vanilla = 1 -- Often solves issues in your ranger config. + vim.g.rnvimr_enable_picker = 1 -- Close rnvimr after choosing a file. + vim.g.rnvimr_ranger_cmd = { "ranger" } -- By passing a script like TERM=foot ranger "$@" you can open terminals inside ranger. + if is_android then -- Open on full screenn + vim.g.rnvimr_layout = { + relative = "editor", + width = 200, + height = 100, + col = 0, + row = 0, + style = "minimal", + } + end + end, + }, + + -- project.nvim [project search + auto cd] + -- https://github.com/ahmedkhalf/project.nvim + { + "zeioth/project.nvim", + event = "User BaseDefered", + cmd = "ProjectRoot", + opts = { + -- How to find root directory + patterns = { + ".git", + "_darcs", + ".hg", + ".bzr", + ".svn", + "Makefile", + "package.json", + ".solution", + ".solution.toml" + }, + -- Don't list the next projects + exclude_dirs = { + "~/" + }, + silent_chdir = true, + manual_mode = false, + + -- Don't chdir for certain buffers + exclude_chdir = { + filetype = {"", "OverseerList", "alpha"}, + buftype = {"nofile", "terminal"}, + }, + + --ignore_lsp = { "lua_ls" }, + }, + config = function(_, opts) require("project_nvim").setup(opts) end, + }, + + -- trim.nvim [auto trim spaces] + -- https://github.com/cappyzawa/trim.nvim + { + "cappyzawa/trim.nvim", + event = "BufWrite", + opts = { + trim_on_write = true, + trim_trailing = true, + trim_last_line = false, + trim_first_line = false, + -- ft_blocklist = { "markdown", "text", "org", "tex", "asciidoc", "rst" }, + -- patterns = {[[%s/\(\n\n\)\n\+/\1/]]}, -- Only one consecutive bl + }, + }, + + -- stickybuf.nvim [lock special buffers] + -- https://github.com/arnamak/stay-centered.nvim + -- By default it support neovim/aerial and others. + { + "stevearc/stickybuf.nvim", + event = "User BaseDefered", + config = function() require("stickybuf").setup() end + }, + + -- mini.bufremove [smart bufdelete] + -- https://github.com/echasnovski/mini.bufremove + -- Defines what tab to go on :bufdelete + { + "echasnovski/mini.bufremove", + event = "User BaseFile" + }, + + -- smart-splits [move and resize buffers] + -- https://github.com/mrjones2014/smart-splits.nvim + { + "mrjones2014/smart-splits.nvim", + event = "User BaseFile", + opts = { + ignored_filetypes = { "nofile", "quickfix", "qf", "prompt" }, + ignored_buftypes = { "nofile" }, + }, + }, + + -- better-scape.nvim [esc] + -- https://github.com/max397574/better-escape.nvim + { + "max397574/better-escape.nvim", + event = "InsertCharPre", + opts = { + mapping = {}, + timeout = 300, + }, + }, + + -- Toggle floating terminal on [term] + -- https://github.com/akinsho/toggleterm.nvim + -- neovim bug → https://github.com/neovim/neovim/issues/21106 + -- workarounds → https://github.com/akinsho/toggleterm.nvim/wiki/Mouse-support + { + "akinsho/toggleterm.nvim", + cmd = { "ToggleTerm", "TermExec" }, + opts = { + highlights = { + Normal = { link = "Normal" }, + NormalNC = { link = "NormalNC" }, + NormalFloat = { link = "Normal" }, + FloatBorder = { link = "FloatBorder" }, + StatusLine = { link = "StatusLine" }, + StatusLineNC = { link = "StatusLineNC" }, + WinBar = { link = "WinBar" }, + WinBarNC = { link = "WinBarNC" }, + }, + size = 10, + open_mapping = [[]], + shading_factor = 2, + direction = "float", + float_opts = { + border = "rounded", + highlights = { border = "Normal", background = "Normal" }, + }, + }, + }, + + -- session-manager [session] + -- https://github.com/Shatur/neovim-session-manager + { + "Shatur/neovim-session-manager", + event = "User BaseDefered", + cmd = "SessionManager", + opts = function() + local config = require('session_manager.config') + return { + autoload_mode = config.AutoloadMode.Disabled, + autosave_last_session = false, + autosave_only_in_session = false, + } + end, + config = function(_, opts) + local session_manager = require('session_manager') + session_manager.setup(opts) + + -- Auto save session + -- BUG: This feature will auto-close anything nofile before saving. + -- This include neotree, aerial, mergetool, among others. + -- Consider commenting the next block if this is important for you. + -- + -- This won't be necessary once neovim fixes: + -- https://github.com/neovim/neovim/issues/12242 + -- vim.api.nvim_create_autocmd({ 'BufWritePre' }, { + -- callback = function () + -- session_manager.save_current_session() + -- end + -- }) + end + }, + + -- spectre.nvim [search and replace in project] + -- https://github.com/nvim-pack/nvim-spectre + -- INSTRUCTIONS: + -- To see the instructions press '?' + -- To start the search press . + -- It doesn't have ctrl-z so please always commit before using it. + { + "nvim-pack/nvim-spectre", + cmd = "Spectre", + opts = { + default = { + find = { + -- pick one of item in find_engine [ fd, rg ] + cmd = "fd", + options = {} + }, + replace = { + -- pick one of item in [ sed, oxi ] + cmd = "sed" + }, + }, + is_insert_mode = true, -- start open panel on is_insert_mode + is_block_ui_break = true, -- prevent the UI from breaking + mapping = { + ["toggle_line"] = { + map = "d", + cmd = "lua require('spectre').toggle_line()", + desc = "toggle item.", + }, + ["enter_file"] = { + map = "", + cmd = "lua require('spectre.actions').select_entry()", + desc = "open file.", + }, + ["send_to_qf"] = { + map = "sqf", + cmd = "lua require('spectre.actions').send_to_qf()", + desc = "send all items to quickfix.", + }, + ["replace_cmd"] = { + map = "src", + cmd = "lua require('spectre.actions').replace_cmd()", + desc = "replace command.", + }, + ["show_option_menu"] = { + map = "so", + cmd = "lua require('spectre').show_options()", + desc = "show options.", + }, + ["run_current_replace"] = { + map = "c", + cmd = "lua require('spectre.actions').run_current_replace()", + desc = "confirm item.", + }, + ["run_replace"] = { + map = "R", + cmd = "lua require('spectre.actions').run_replace()", + desc = "replace all.", + }, + ["change_view_mode"] = { + map = "sv", + cmd = "lua require('spectre').change_view()", + desc = "results view mode.", + }, + ["change_replace_sed"] = { + map = "srs", + cmd = "lua require('spectre').change_engine_replace('sed')", + desc = "use sed to replace.", + }, + ["change_replace_oxi"] = { + map = "sro", + cmd = "lua require('spectre').change_engine_replace('oxi')", + desc = "use oxi to replace.", + }, + ["toggle_live_update"] = { + map = "sar", + cmd = "lua require('spectre').toggle_live_update()", + desc = "auto refresh changes when nvim writes a file.", + }, + ["resume_last_search"] = { + map = "sl", + cmd = "lua require('spectre').resume_last_search()", + desc = "repeat last search.", + }, + ["insert_qwerty"] = { + map = "i", + cmd = "startinsert", + desc = "insert (qwerty).", + }, + ["insert_colemak"] = { + map = "o", + cmd = "startinsert", + desc = "insert (colemak).", + }, + ["quit"] = { + map = "q", + cmd = "lua require('spectre').close()", + desc = "quit.", + }, + }, + }, + }, + + -- [neotree] + -- https://github.com/nvim-neo-tree/neo-tree.nvim + { + "nvim-neo-tree/neo-tree.nvim", + dependencies = "MunifTanjim/nui.nvim", + cmd = "Neotree", + opts = function() + vim.g.neo_tree_remove_legacy_commands = true + local utils = require("base.utils") + local get_icon = utils.get_icon + return { + auto_clean_after_session_restore = true, + close_if_last_window = true, + buffers = { + show_unloaded = true + }, + sources = { "filesystem", "buffers", "git_status" }, + source_selector = { + winbar = true, + content_layout = "center", + sources = { + { + source = "filesystem", + display_name = get_icon("FolderClosed", 1, true) .. "File", + }, + { + source = "buffers", + display_name = get_icon("DefaultFile", 1, true) .. "Bufs", + }, + { + source = "git_status", + display_name = get_icon("Git", 1, true) .. "Git", + }, + { + source = "diagnostics", + display_name = get_icon("Diagnostic", 1, true) .. "Diagnostic", + }, + }, + }, + default_component_configs = { + indent = { padding = 0 }, + icon = { + folder_closed = get_icon("FolderClosed"), + folder_open = get_icon("FolderOpen"), + folder_empty = get_icon("FolderEmpty"), + folder_empty_open = get_icon("FolderEmpty"), + default = get_icon "DefaultFile", + }, + modified = { symbol = get_icon "FileModified" }, + git_status = { + symbols = { + added = get_icon("GitAdd"), + deleted = get_icon("GitDelete"), + modified = get_icon("GitChange"), + renamed = get_icon("GitRenamed"), + untracked = get_icon("GitUntracked"), + ignored = get_icon("GitIgnored"), + unstaged = get_icon("GitUnstaged"), + staged = get_icon("GitStaged"), + conflict = get_icon("GitConflict"), + }, + }, + }, + -- A command is a function that we can assign to a mapping (below) + commands = { + system_open = function(state) + require("base.utils").open_with_program(state.tree:get_node():get_id()) + end, + parent_or_close = function(state) + local node = state.tree:get_node() + if + (node.type == "directory" or node:has_children()) + and node:is_expanded() + then + state.commands.toggle_node(state) + else + require("neo-tree.ui.renderer").focus_node( + state, + node:get_parent_id() + ) + end + end, + child_or_open = function(state) + local node = state.tree:get_node() + if node.type == "directory" or node:has_children() then + if not node:is_expanded() then -- if unexpanded, expand + state.commands.toggle_node(state) + else -- if expanded and has children, seleect the next child + require("neo-tree.ui.renderer").focus_node( + state, + node:get_child_ids()[1] + ) + end + else -- if not a directory just open it + state.commands.open(state) + end + end, + copy_selector = function(state) + local node = state.tree:get_node() + local filepath = node:get_id() + local filename = node.name + local modify = vim.fn.fnamemodify + + local results = { + e = { val = modify(filename, ":e"), msg = "Extension only" }, + f = { val = filename, msg = "Filename" }, + F = { + val = modify(filename, ":r"), + msg = "Filename w/o extension", + }, + h = { + val = modify(filepath, ":~"), + msg = "Path relative to Home", + }, + p = { + val = modify(filepath, ":."), + msg = "Path relative to CWD", + }, + P = { val = filepath, msg = "Absolute path" }, + } + + local messages = { + { "\nChoose to copy to clipboard:\n", "Normal" }, + } + for i, result in pairs(results) do + if result.val and result.val ~= "" then + vim.list_extend(messages, { + { ("%s."):format(i), "Identifier" }, + { (" %s: "):format(result.msg) }, + { result.val, "String" }, + { "\n" }, + }) + end + end + vim.api.nvim_echo(messages, false, {}) + local result = results[vim.fn.getcharstr()] + if result and result.val and result.val ~= "" then + vim.notify("Copied: " .. result.val) + vim.fn.setreg("+", result.val) + end + end, + find_in_dir = function(state) + local node = state.tree:get_node() + local path = node:get_id() + require("telescope.builtin").find_files { + cwd = node.type == "directory" and path + or vim.fn.fnamemodify(path, ":h"), + } + end, + }, + window = { + width = 30, + mappings = { + [""] = false, -- disable space until we figure out which-key disabling + [""] = "system_open", + ["[b"] = "prev_source", + ["]b"] = "next_source", + F = utils.is_available "telescope.nvim" and "find_in_dir" or nil, + O = "system_open", + Y = "copy_selector", + h = "parent_or_close", + l = "child_or_open", + }, + }, + filesystem = { + follow_current_file = { + enabled = true, + }, + hijack_netrw_behavior = "open_current", + use_libuv_file_watcher = true, + }, + event_handlers = { + { + event = "neo_tree_buffer_enter", + handler = function(_) vim.opt_local.signcolumn = "auto" end, + }, + }, + } + end, + }, + + -- code [folding mod] + [promise-asyn] dependency + -- https://github.com/kevinhwang91/nvim-ufo + -- https://github.com/kevinhwang91/promise-async + { + "kevinhwang91/nvim-ufo", + event = { "User BaseFile" }, + dependencies = { "kevinhwang91/promise-async" }, + opts = { + preview = { + mappings = { + scrollB = "", + scrollF = "", + scrollU = "", + scrollD = "", + }, + }, + provider_selector = function(_, filetype, buftype) + local function handleFallbackException(bufnr, err, providerName) + if type(err) == "string" and err:match "UfoFallbackException" then + return require("ufo").getFolds(bufnr, providerName) + else + return require("promise").reject(err) + end + end + + -- only use indent until a file is opened + return (filetype == "" or buftype == "nofile") and "indent" + or function(bufnr) + return require("ufo") + .getFolds(bufnr, "lsp") + :catch( + function(err) + return handleFallbackException(bufnr, err, "treesitter") + end + ) + :catch( + function(err) + return handleFallbackException(bufnr, err, "indent") + end + ) + end + end, + }, + }, + + -- nvim-neoclip [nvim clipboard] + -- https://github.com/AckslD/nvim-neoclip.lua + -- Read their docs to enable cross-session history. + { + "AckslD/nvim-neoclip.lua", + requires = 'nvim-telescope/telescope.nvim', + event = "User BaseFile", + opts = {} + }, + + -- zen-mode.nvim [distraction free mode] + -- https://github.com/folke/zen-mode.nvim + { + "folke/zen-mode.nvim", + cmd = "ZenMode", + }, + + -- suda.nvim [write as sudo] + -- https://github.com/lambdalisue/suda.vim + { + "lambdalisue/suda.vim", + cmd = { "SudaRead", "SudaWrite" }, + }, + + -- vim-matchup [improved % motion] + -- https://github.com/andymass/vim-matchup + { + "andymass/vim-matchup", + event = "User BaseFile", + config = function() + vim.g.matchup_matchparen_deferred = 1 -- work async + vim.g.matchup_matchparen_offscreen = {} -- disable status bar icon + end, + }, + + -- hop.nvim [go to word visually] + -- https://github.com/smoka7/hop.nvim + { + "smoka7/hop.nvim", + cmd = { "HopWord" }, + opts = { keys = "etovxqpdygfblzhckisuran" } + }, + + -- nvim-autopairs [auto close brackets] + -- https://github.com/windwp/nvim-autopairs + -- It's disabled by default, you can enable it with ua + { + "windwp/nvim-autopairs", + event = "InsertEnter", + opts = { + check_ts = true, + ts_config = { java = false }, + fast_wrap = { + map = "", + chars = { "{", "[", "(", '"', "'" }, + pattern = string.gsub([[ [%'%"%)%>%]%)%}%,] ]], "%s+", ""), + offset = 0, + end_key = "$", + keys = "qwertyuiopzxcvbnmasdfghjkl", + check_comma = true, + highlight = "PmenuSel", + highlight_grey = "LineNr", + }, + }, + config = function(_, opts) + local npairs = require("nvim-autopairs") + npairs.setup(opts) + if not vim.g.autopairs_enabled then npairs.disable() end + + local is_cmp_loaded, cmp = pcall(require, "cmp") + if is_cmp_loaded then + cmp.event:on( + "confirm_done", + require("nvim-autopairs.completion.cmp").on_confirm_done { + tex = false } + ) + end + end + }, + + -- lsp_signature.nvim [auto params help] + -- https://github.com/ray-x/lsp_signature.nvim + { + "ray-x/lsp_signature.nvim", + event = "User BaseFile", + opts = function() + -- Apply globals from 1-options.lua + local is_enabled = vim.g.lsp_signature_enabled + local round_borders = {} + if vim.g.lsp_round_borders_enabled then + round_borders = { border = 'rounded' } + end + return { + -- Window mode + floating_window = is_enabled, -- Display it as floating window. + hi_parameter = "IncSearch", -- Color to highlight floating window. + handler_opts = round_borders, -- Window style + + -- Hint mode + hint_enable = false, -- Display it as hint. + hint_prefix = "👈 ", + + -- Additionally, you can use uH to toggle inlay hints. + toggle_key_flip_floatwin_setting = is_enabled + } + end, + config = function(_, opts) require('lsp_signature').setup(opts) end + }, + + -- nvim-lightbulb [lightbulb for code actions] + -- https://github.com/kosayoda/nvim-lightbulb + -- Show a lightbulb where a code action is available + { + 'kosayoda/nvim-lightbulb', + enabled = vim.g.codeactions_enabled, + event = "User BaseFile", + opts = { + action_kinds = { -- show only for relevant code actions. + "quickfix", + }, + ignore = { + ft = { "lua" }, -- ignore filetypes with bad code actions. + }, + autocmd = { + enabled = true, + updatetime = 100, + }, + sign = { enabled = false }, + virtual_text = { + enabled = true, + text = "💡" + } + }, + config = function(_, opts) require("nvim-lightbulb").setup(opts) end + }, + + -- distroupdate.nvim [distro update] + -- https://github.com/zeioth/distroupdate.nvim + { + "zeioth/distroupdate.nvim", + dependencies = { "nvim-lua/plenary.nvim" }, + cmd = { + "DistroFreezePluginVersions", + "DistroReadChangelog", + "DistroReadVersion", + "DistroUpdate", + "DistroUpdateRevert" + }, + opts = function() + local utils = require("base.utils") + local config_dir = utils.os_path(vim.fn.stdpath "config" .. "/lua/base/") + return { + channel = "stable", -- stable/nightly + hot_reload_files = { + config_dir .. "1-options.lua", + config_dir .. "4-mappings.lua" + }, + hot_reload_callback = function() + vim.cmd(":silent! colorscheme " .. base.default_colorscheme) -- nvim colorscheme reload command + vim.cmd(":silent! doautocmd ColorScheme") -- heirline colorscheme reload event + end + } + end + }, + +} -- end of return diff --git a/dot_config/nvim/lua/plugins/2-ui.lua b/dot_config/nvim/lua/plugins/2-ui.lua new file mode 100644 index 0000000000000000000000000000000000000000..1330e274ae288a18fdff60868067abda6cbbf2d9 --- /dev/null +++ b/dot_config/nvim/lua/plugins/2-ui.lua @@ -0,0 +1,709 @@ +-- User interface +-- Things that make the GUI better. + +-- Sections: +-- -> tokyonight [theme] +-- -> astrotheme [theme] +-- -> alpha-nvim [greeter] +-- -> nvim-notify [notifications] +-- -> mini.indentscope [guides] +-- -> heirline-components.nvim [ui components] +-- -> heirline [ui components] +-- -> telescope [search] +-- -> telescope-fzf-native.nvim [search backend] +-- -> smart-splits [window-dimming] +-- -> dressing.nvim [better ui elements] +-- -> noice.nvim [better cmd/search line] +-- -> nvim-web-devicons [icons | ui] +-- -> lspkind.nvim [icons | lsp] +-- -> nvim-scrollbar [scrollbar] +-- -> mini.animate [animations] +-- -> highlight-undo [highlights] +-- -> which-key [on-screen keybinding] + +local utils = require "base.utils" +local is_windows = vim.fn.has('win32') == 1 -- true if on windows +local is_android = vim.fn.isdirectory('/data') == 1 -- true if on android + +return { + + -- tokyonight [theme] + -- https://github.com/folke/tokyonight.nvim + { + "zeioth/tokyonight.nvim", + event = "User LoadColorSchemes", + opts = { + dim_inactive = false, + styles = { + comments = { italic = true }, + keywords = { italic = true }, + }, + } + }, + + -- astrotheme [theme] + -- https://github.com/AstroNvim/astrotheme + { + "AstroNvim/astrotheme", + event = "User LoadColorSchemes", + opts = { + palette = "astrodark", + plugins = { ["dashboard-nvim"] = true }, + }, + }, + + -- alpha-nvim [greeter] + -- https://github.com/goolord/alpha-nvim + { + "goolord/alpha-nvim", + cmd = "Alpha", + -- setup header and buttonts + opts = function() + local dashboard = require("alpha.themes.dashboard") + + -- Header + -- dashboard.section.header.val = { + -- "  ", + -- " ████ ██████ █████ ██ ", + -- " ███████████ █████  ", + -- " █████████ ███████████████████ ███ ███████████ ", + -- " █████████ ███ █████████████ █████ ██████████████ ", + -- " █████████ ██████████ █████████ █████ █████ ████ █████ ", + -- " ███████████ ███ ███ █████████ █████ █████ ████ █████ ", + -- " ██████ █████████████████████ ████ █████ █████ ████ ██████ ", + -- } + -- dashboard.section.header.val = { + -- ' ▟▙ ', + -- ' ▝▘ ', + -- '██▃▅▇█▆▖ ▗▟████▙▖ ▄████▄ ██▄ ▄██ ██ ▗▟█▆▄▄▆█▙▖', + -- '██▛▔ ▝██ ██▄▄▄▄██ ██▛▔▔▜██ ▝██ ██▘ ██ ██▛▜██▛▜██', + -- '██ ██ ██▀▀▀▀▀▘ ██▖ ▗██ ▜█▙▟█▛ ██ ██ ██ ██', + -- '██ ██ ▜█▙▄▄▄▟▊ ▀██▙▟██▀ ▝████▘ ██ ██ ██ ██', + -- '▀▀ ▀▀ ▝▀▀▀▀▀ ▀▀▀▀ ▀▀ ▀▀ ▀▀ ▀▀ ▀▀', + -- } + -- dashboard.section.header.val = { + -- ' ▟▙ ', + -- ' ▝▘ ', + -- '██▃▅▇█▆▖ ██▄ ▄██ ██ ▗▟█▆▄▄▆█▙▖', + -- '██▛▔ ▝██ ▝██ ██▘ ██ ██▛▜██▛▜██', + -- '██ ██ ▜█▙▟█▛ ██ ██ ██ ██', + -- '██ ██ ▝████▘ ██ ██ ██ ██', + -- '▀▀ ▀▀ ▀▀ ▀▀ ▀▀ ▀▀ ▀▀', + -- } + -- Generated with https://www.fancytextpro.com/BigTextGenerator/Larry3D + -- dashboard.section.header.val = { + -- [[ __ __ __ __ ]], + -- [[/\ \/\ \ /\ \/\ \ __ ]], + -- [[\ \ `\\ \ __ ___ \ \ \ \ \/\_\ ___ ___ ]], + -- [[ \ \ , ` \ /'__`\ / __`\\ \ \ \ \/\ \ /' __` __`\ ]], + -- [[ \ \ \`\ \/\ __//\ \L\ \\ \ \_/ \ \ \/\ \/\ \/\ \ ]], + -- [[ \ \_\ \_\ \____\ \____/ \ `\___/\ \_\ \_\ \_\ \_\]], + -- [[ \/_/\/_/\/____/\/___/ `\/__/ \/_/\/_/\/_/\/_/]], + -- } + -- dashboard.section.header.val = { + -- ' ', + -- ' ███╗ ██╗███████╗ ██████╗ ██╗ ██╗██╗███╗ ███╗ ', + -- ' ████╗ ██║██╔════╝██╔═══██╗██║ ██║██║████╗ ████║ ', + -- ' ██╔██╗ ██║█████╗ ██║ ██║██║ ██║██║██╔████╔██║ ', + -- ' ██║╚██╗██║██╔══╝ ██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║ ', + -- ' ██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ ', + -- ' ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═══╝ ╚═╝╚═╝ ╚═╝ ', + -- ' ', + -- } + -- dashboard.section.header.val = { + -- [[ __ ]], + -- [[ ___ __ __ /\_\ ___ ___ ]], + -- [[/' _ `\/\ \/\ \\/\ \ /' __` __`\ ]], + -- [[/\ \/\ \ \ \_/ |\ \ \/\ \/\ \/\ \ ]], + -- [[\ \_\ \_\ \___/ \ \_\ \_\ \_\ \_\]], + -- [[ \/_/\/_/\/__/ \/_/\/_/\/_/\/_/]], + -- } + + if is_android then + dashboard.section.header.val = { + [[ __ ]], + [[ __ __ /\_\ ___ ___ ]], + [[/\ \/\ \\/\ \ /' __` __`\ ]], + [[\ \ \_/ |\ \ \/\ \/\ \/\ \ ]], + [[ \ \___/ \ \_\ \_\ \_\ \_\]], + [[ \/__/ \/_/\/_/\/_/\/_/]], + } + else + dashboard.section.header.val = { + [[888b 88 88]], + [[8888b 88 88]], + [[88 `8b 88 88]], + [[88 `8b 88 ,adPPYba, 8b,dPPYba, 88,dPYba,,adPYba, ,adPPYYba, 88]], + [[88 `8b 88 a8" "8a 88P' "Y8 88P' "88" "8a "" `Y8 88]], + [[88 `8b 88 8b d8 88 88 88 88 ,adPPPPP88 88]], + [[88 `8888 "8a, ,a8" 88 88 88 88 88, ,88 88]], + [[88 `888 `"YbbdP"' 88 88 88 88 `"8bbdP"Y8 88]], + [[ __ ]], + [[ ___ __ __ /\_\ ___ ___ ]], + [[ /' _ `\/\ \/\ \\/\ \ /' __` __`\ ]], + [[ /\ \/\ \ \ \_/ |\ \ \/\ \/\ \/\ \ ]], + [[ \ \_\ \_\ \___/ \ \_\ \_\ \_\ \_\]], + [[ \/_/\/_/\/__/ \/_/\/_/\/_/\/_/]], + } + end + + dashboard.section.header.opts.hl = "DashboardHeader" + vim.cmd "highlight DashboardHeader guifg=#F7778F" + + -- If on windows, don't show the 'ranger' button + local ranger_button = dashboard.button("r", "🐍 Ranger ", "RnvimrToggle") + if is_windows then ranger_button = nil end + + -- Buttons + dashboard.section.buttons.val = { + dashboard.button("n", "📄 New ", "ene"), + dashboard.button("e", "🌺 Recent ", "Telescope oldfiles"), + ranger_button, + dashboard.button( + "s", + "🔎 Sessions", + "SessionManager! load_session" + ), + dashboard.button("p", "💼 Projects", "Telescope projects"), + dashboard.button("", ""), + dashboard.button("q", " Quit", "exit"), + -- --button("LDR f '", " Bookmarks "), + } + + -- Vertical margins + dashboard.config.layout[1].val = + vim.fn.max { 2, vim.fn.floor(vim.fn.winheight(0) * 0.10) } -- Above header + dashboard.config.layout[3].val = + vim.fn.max { 2, vim.fn.floor(vim.fn.winheight(0) * 0.10) } -- Above buttons + + -- Disable autocmd and return + dashboard.config.opts.noautocmd = true + return dashboard + end, + config = function(_, opts) + -- Footer + require("alpha").setup(opts.config) + vim.api.nvim_create_autocmd("User", { + pattern = "LazyVimStarted", + desc = "Add Alpha dashboard footer", + once = true, + callback = function() + local stats = require("lazy").stats() + stats.real_cputime = not is_windows + local ms = math.floor(stats.startuptime * 100 + 0.5) / 100 + opts.section.footer.val = { + " ", + " ", + " ", + "Loaded " .. stats.loaded .. " plugins  in " .. ms .. "ms", + ".............................", + } + opts.section.footer.opts.hl = "DashboardFooter" + vim.cmd "highlight DashboardFooter guifg=#D29B68" + pcall(vim.cmd.AlphaRedraw) + end, + }) + end, + }, + + -- [notifications] + -- https://github.com/rcarriga/nvim-notify + { + "rcarriga/nvim-notify", + event = "User BaseDefered", + opts = function() + local fps + if is_android then fps = 30 else fps = 144 end + + return { + timeout = 2500, + fps = fps, + max_height = function() return math.floor(vim.o.lines * 0.75) end, + max_width = function() return math.floor(vim.o.columns * 0.75) end, + on_open = function(win) + -- enable markdown support on notifications + vim.api.nvim_win_set_config(win, { zindex = 175 }) + if not vim.g.notifications_enabled then + vim.api.nvim_win_close(win, true) + end + if not package.loaded["nvim-treesitter"] then + pcall(require, "nvim-treesitter") + end + vim.wo[win].conceallevel = 3 + local buf = vim.api.nvim_win_get_buf(win) + if not pcall(vim.treesitter.start, buf, "markdown") then + vim.bo[buf].syntax = "markdown" + end + vim.wo[win].spell = false + end, + } + end, + config = function(_, opts) + local notify = require("notify") + notify.setup(opts) + vim.notify = notify + end, + }, + + -- mini.indentscope [guides] + -- https://github.com/echasnovski/mini.indentscope + { + "echasnovski/mini.indentscope", + event = { "BufReadPre", "BufNewFile" }, + opts = { + draw = { delay = 0, animation = function() return 0 end }, + options = { border = "top", try_as_border = true }, + symbol = "▏", + }, + config = function(_, opts) + require("mini.indentscope").setup(opts) + + -- Disable for certain filetypes + vim.api.nvim_create_autocmd({ "FileType" }, { + desc = "Disable indentscope for certain filetypes", + callback = function() + local ignored_filetypes = { + "aerial", + "dashboard", + "help", + "lazy", + "leetcode.nvim", + "mason", + "neo-tree", + "NvimTree", + "neogitstatus", + "notify", + "startify", + "toggleterm", + "Trouble", + "calltree", + "coverage" + } + if vim.tbl_contains(ignored_filetypes, vim.bo.filetype) then + vim.b.miniindentscope_disable = true + end + end, + }) + end + }, + + -- heirline-components.nvim [ui components] + -- https://github.com/zeioth/heirline-components.nvim + -- Collection of components to use on your heirline config. + { + "zeioth/heirline-components.nvim", + opts = { + icons = require("base.icons.nerd_font") + } + }, + + -- heirline [ui components] + -- https://github.com/rebelot/heirline.nvim + -- Use it to customize the components of your user interface, + -- Including tabline, winbar, statuscolumn, statusline. + -- Be aware some components are positional. Read heirline documentation. + { + "rebelot/heirline.nvim", + dependencies = { "zeioth/heirline-components.nvim" }, + event = "User BaseDefered", + opts = function() + local lib = require "heirline-components.all" + return { + opts = { + disable_winbar_cb = function(args) -- We do this to avoid showing it on the greeter. + local is_disabled = not require("heirline-components.buffer").is_valid(args.buf) or + lib.condition.buffer_matches({ + buftype = { "terminal", "prompt", "nofile", "help", "quickfix" }, + filetype = { "NvimTree", "neo%-tree", "dashboard", "Outline", "aerial" }, + }, args.buf) + return is_disabled + end, + }, + tabline = { -- UI upper bar + lib.component.tabline_conditional_padding(), + lib.component.tabline_buffers(), + lib.component.fill { hl = { bg = "tabline_bg" } }, + lib.component.tabline_tabpages() + }, + winbar = { -- UI breadcrumbs bar + init = function(self) self.bufnr = vim.api.nvim_get_current_buf() end, + fallthrough = false, + -- Winbar for terminal, neotree, and aerial. + { + condition = function() return not lib.condition.is_active() end, + { + lib.component.neotree(), + lib.component.compiler_play(), + lib.component.fill(), + lib.component.compiler_redo(), + lib.component.aerial(), + }, + }, + -- Regular winbar + { + lib.component.neotree(), + lib.component.compiler_play(), + lib.component.fill(), + lib.component.breadcrumbs(), + lib.component.fill(), + lib.component.compiler_redo(), + lib.component.aerial(), + } + }, + statuscolumn = { -- UI left column + init = function(self) self.bufnr = vim.api.nvim_get_current_buf() end, + lib.component.foldcolumn(), + lib.component.numbercolumn(), + lib.component.signcolumn(), + } or nil, + statusline = { -- UI statusbar + hl = { fg = "fg", bg = "bg" }, + lib.component.mode(), + lib.component.git_branch(), + lib.component.file_info(), + lib.component.git_diff(), + lib.component.diagnostics(), + lib.component.fill(), + lib.component.cmd_info(), + lib.component.fill(), + lib.component.lsp(), + lib.component.compiler_state(), + lib.component.virtual_env(), + lib.component.nav(), + lib.component.mode { surround = { separator = "right" } }, + }, + } + end, + config = function(_, opts) + local heirline = require("heirline") + local heirline_components = require "heirline-components.all" + + -- Setup + heirline_components.init.subscribe_to_events() + heirline.load_colors(heirline_components.hl.get_colors()) + heirline.setup(opts) + end, + }, + + -- Telescope [search] + [search backend] dependency + -- https://github.com/nvim-telescope/telescope.nvim + -- https://github.com/nvim-telescope/telescope-fzf-native.nvim + -- https://github.com/debugloop/telescope-undo.nvim + -- NOTE: Normally, plugins that depend on Telescope are defined separately. + -- But its Telescope extension is added in the Telescope 'config' section. + { + "nvim-telescope/telescope.nvim", + dependencies = { + { + "debugloop/telescope-undo.nvim", + cmd = "Telescope", + }, + { + "nvim-telescope/telescope-fzf-native.nvim", + enabled = vim.fn.executable "make" == 1, + build = "make", + }, + }, + cmd = "Telescope", + opts = function() + local get_icon = require("base.utils").get_icon + local actions = require("telescope.actions") + local mappings = { + i = { + [""] = actions.cycle_history_next, + [""] = actions.cycle_history_prev, + [""] = actions.move_selection_next, + [""] = actions.move_selection_previous, + [""] = actions.close, + [""] = false, + }, + n = { ["q"] = actions.close }, + } + return { + defaults = { + prompt_prefix = get_icon("Selected", 1), + selection_caret = get_icon("Selected", 1), + multi_icon = get_icon("selected", 1), + path_display = { "truncate" }, + sorting_strategy = "ascending", + layout_config = { + horizontal = { + prompt_position = "top", + preview_width = 0.50, + }, + vertical = { + mirror = false, + }, + width = 0.87, + height = 0.80, + preview_cutoff = 120, + }, + mappings = mappings, + }, + extensions = { + undo = { + use_delta = true, + side_by_side = true, + diff_context_lines = 0, + entry_format = "󰣜 #$ID, $STAT, $TIME", + layout_strategy = "horizontal", + layout_config = { + preview_width = 0.65, + }, + mappings = { + i = { + [""] = require("telescope-undo.actions").yank_additions, + [""] = require("telescope-undo.actions").yank_deletions, + [""] = require("telescope-undo.actions").restore, + }, + }, + }, + }, + } + end, + config = function(_, opts) + local telescope = require("telescope") + telescope.setup(opts) + -- Here we define the Telescope extension for all plugins. + -- If you delete a plugin, you can also delete its Telescope extension. + if utils.is_available("nvim-notify") then telescope.load_extension("notify") end + if utils.is_available("telescope-fzf-native.nvim") then telescope.load_extension("fzf") end + if utils.is_available("telescope-undo.nvim") then telescope.load_extension("undo") end + if utils.is_available("project.nvim") then telescope.load_extension("projects") end + if utils.is_available("LuaSnip") then telescope.load_extension("luasnip") end + if utils.is_available("aerial.nvim") then telescope.load_extension("aerial") end + if utils.is_available("nvim-neoclip.lua") then + telescope.load_extension("neoclip") + telescope.load_extension("macroscope") + end + end, + }, + + -- [better ui elements] + -- https://github.com/stevearc/dressing.nvim + { + "stevearc/dressing.nvim", + event = "User BaseDefered", + opts = { + input = { default_prompt = "➤ " }, + select = { backend = { "telescope", "builtin" } }, + } + }, + + -- Noice.nvim [better cmd/search line] + -- https://github.com/folke/noice.nvim + -- We use it for: + -- * cmdline: Display treesitter for : + -- * search: Display a magnifier instead of / + -- + -- We don't use it for: + -- * LSP status: We use a heirline component for this. + -- * Search results: We use a heirline component for this. + { + "folke/noice.nvim", + event = "User BaseDefered", + opts = function() + local enable_conceal = false -- Hide command text if true + return { + presets = { bottom_search = true }, -- The kind of popup used for / + cmdline = { + view = "cmdline", -- The kind of popup used for : + format = { + cmdline = { conceal = enable_conceal }, + search_down = { conceal = enable_conceal }, + search_up = { conceal = enable_conceal }, + filter = { conceal = enable_conceal }, + lua = { conceal = enable_conceal }, + help = { conceal = enable_conceal }, + input = { conceal = enable_conceal }, + } + }, + + -- Disable every other noice feature + messages = { enabled = false }, + lsp = { + hover = { enabled = false }, + signature = { enabled = false }, + progress = { enabled = false }, + message = { enabled = false }, + smart_move = { enabled = false }, + }, + } + end + }, + + -- UI icons [icons] + -- https://github.com/nvim-tree/nvim-web-devicons + { + "nvim-tree/nvim-web-devicons", + enabled = vim.g.icons_enabled, + event = "User BaseDefered", + opts = { + override = { + default_icon = { + icon = require("base.utils").get_icon("DefaultFile"), + name = "default" + }, + deb = { icon = "", name = "Deb" }, + lock = { icon = "󰌾", name = "Lock" }, + mp3 = { icon = "󰎆", name = "Mp3" }, + mp4 = { icon = "", name = "Mp4" }, + out = { icon = "", name = "Out" }, + ["robots.txt"] = { icon = "󰚩", name = "Robots" }, + ttf = { icon = "", name = "TrueTypeFont" }, + rpm = { icon = "", name = "Rpm" }, + woff = { icon = "", name = "WebOpenFontFormat" }, + woff2 = { icon = "", name = "WebOpenFontFormat2" }, + xz = { icon = "", name = "Xz" }, + zip = { icon = "", name = "Zip" }, + }, + }, + config = function(_, opts) + require("nvim-web-devicons").setup(opts) + pcall(vim.api.nvim_del_user_command, "NvimWebDeviconsHiTest") + end + }, + + -- LSP icons [icons] + -- https://github.com/onsails/lspkind.nvim + { + "onsails/lspkind.nvim", + opts = { + mode = "symbol", + symbol_map = { + Array = "󰅪", + Boolean = "⊨", + Class = "󰌗", + Constructor = "", + Key = "󰌆", + Namespace = "󰅪", + Null = "NULL", + Number = "#", + Object = "󰀚", + Package = "󰏗", + Property = "", + Reference = "", + Snippet = "", + String = "󰀬", + TypeParameter = "󰊄", + Unit = "", + }, + menu = {}, + }, + enabled = vim.g.icons_enabled, + config = function(_, opts) + require("lspkind").init(opts) + end, + }, + + -- nvim-scrollbar [scrollbar] + -- https://github.com/petertriho/nvim-scrollbar + { + "petertriho/nvim-scrollbar", + event = "User BaseFile", + opts = { + handlers = { + gitsigns = true, -- gitsigns integration (display hunks) + ale = true, -- lsp integration (display errors/warnings) + search = false, -- hlslens integration (display search result) + }, + excluded_filetypes = { + "cmp_docs", + "cmp_menu", + "noice", + "prompt", + "TelescopePrompt", + "alpha", + }, + }, + }, + + -- mini.animate [animations] + -- https://github.com/echasnovski/mini.animate + -- HINT: if one of your personal keymappings fail due to mini.animate, try to + -- disable it during the keybinding using vim.g.minianimate_disable = true + { + "echasnovski/mini.animate", + event = "User BaseFile", + enabled = not is_android, + opts = function() + -- don't use animate when scrolling with the mouse + local mouse_scrolled = false + for _, scroll in ipairs { "Up", "Down" } do + local key = "" + vim.keymap.set({ "", "i" }, key, function() + mouse_scrolled = true + return key + end, { expr = true }) + end + + local animate = require("mini.animate") + return { + open = { enable = false }, -- true causes issues on nvim-spectre + resize = { + timing = animate.gen_timing.linear { duration = 33, unit = "total" }, + }, + scroll = { + timing = animate.gen_timing.linear { duration = 50, unit = "total" }, + subscroll = animate.gen_subscroll.equal { + predicate = function(total_scroll) + if mouse_scrolled then + mouse_scrolled = false + return false + end + return total_scroll > 1 + end, + }, + }, + cursor = { + enable = false, -- We don't want cursor ghosting + timing = animate.gen_timing.linear { duration = 26, unit = "total" }, + }, + } + end, + }, + + -- highlight-undo + -- https://github.com/tzachar/highlight-undo.nvim + -- This plugin only flases on redo. + -- But we also have a autocmd to flash on yank. + { + "tzachar/highlight-undo.nvim", + event = "User BaseDefered", + opts = { + hlgroup = "CurSearch", + duration = 150, + keymaps = { + { "n", "u", "undo", {} }, -- If you remap undo/redo, change this + { "n", "", "redo", {} }, + }, + }, + config = function(_, opts) + require("highlight-undo").setup(opts) + + -- Also flash on yank. + vim.api.nvim_create_autocmd("TextYankPost", { + desc = "Highlight yanked text", + pattern = "*", + callback = function() vim.highlight.on_yank() end, + }) + end, + }, + + -- which-key.nvim [on-screen keybindings] + -- https://github.com/folke/which-key.nvim + { + "folke/which-key.nvim", + event = "User BaseDefered", + opts = { + icons = { group = vim.g.icons_enabled and "" or "+", separator = "" }, + disable = { filetypes = { "TelescopePrompt" } }, + }, + config = function(_, opts) + require("which-key").setup(opts) + require("base.utils").which_key_register() + end, + }, + + +} -- end of return diff --git a/dot_config/nvim/lua/plugins/3-dev-core.lua b/dot_config/nvim/lua/plugins/3-dev-core.lua new file mode 100644 index 0000000000000000000000000000000000000000..47f444b827d10061e7b612787a7e399148de9797 --- /dev/null +++ b/dot_config/nvim/lua/plugins/3-dev-core.lua @@ -0,0 +1,510 @@ +-- Dev core +-- Things that are just there. + +-- Sections: +-- ## TREE SITTER +-- -> nvim-treesitter [syntax highlight] +-- -> nvim-ts-autotag [treesitter understand html tags] +-- -> ts-comments.nvim [treesitter comments] +-- -> nvim-colorizer [hex colors] + +-- ## LSP +-- -> nvim-java [java support] +-- -> mason-lspconfig [auto start lsp] +-- -> nvim-lspconfig [lsp configs] +-- -> mason.nvim [lsp package manager] +-- -> SchemaStore.nvim [mason extra schemas] +-- -> none-ls-autoload.nvim [mason package loader] +-- -> none-ls [lsp code formatting] +-- -> neodev [lsp for nvim lua api] +-- -> garbage-day [lsp garbage collector] + +-- ## AUTO COMPLETION +-- -> nvim-cmp [auto completion engine] +-- -> cmp-nvim-buffer [auto completion buffer] +-- -> cmp-nvim-path [auto completion path] +-- -> cmp-nvim-lsp [auto completion lsp] +-- -> cmp-luasnip [auto completion snippets] + +local utils = require("base.utils") +local utils_lsp = require("base.utils.lsp") + +return { + -- TREE SITTER --------------------------------------------------------- + -- [syntax highlight] + [treesitter understand html tags] + [comments] + -- https://github.com/nvim-treesitter/nvim-treesitter + -- https://github.com/windwp/nvim-ts-autotag + -- https://github.com/windwp/nvim-treesitter-textobjects + { + "nvim-treesitter/nvim-treesitter", + dependencies = { + "windwp/nvim-ts-autotag", + "nvim-treesitter/nvim-treesitter-textobjects", + }, + event = "User BaseDefered", + cmd = { + "TSBufDisable", + "TSBufEnable", + "TSBufToggle", + "TSDisable", + "TSEnable", + "TSToggle", + "TSInstall", + "TSInstallInfo", + "TSInstallSync", + "TSModuleInfo", + "TSUninstall", + "TSUpdate", + "TSUpdateSync", + }, + build = ":TSUpdate", + init = function(plugin) + -- perf: make treesitter queries available at startup. + require("lazy.core.loader").add_to_rtp(plugin) + require("nvim-treesitter.query_predicates") + end, + opts = { + auto_install = false, -- Currently bugged. Use [:TSInstall all] and [:TSUpdate all] + autotag = { enable = true }, + highlight = { + enable = true, + disable = function(_, bufnr) + local excluded_filetypes = {} -- disabled for + local is_disabled = vim.tbl_contains( + excluded_filetypes, vim.bo.filetype) or utils.is_big_file(bufnr) + return is_disabled + end, + }, + matchup = { + enable = true, + enable_quotes = true, + disable = function(_, bufnr) + local excluded_filetypes = {} -- disabled for + local is_disabled = vim.tbl_contains( + excluded_filetypes, vim.bo.filetype) or utils.is_big_file(bufnr) + return is_disabled + end, + }, + incremental_selection = { enable = true }, + indent = { enable = true }, + textobjects = { + select = { + enable = true, + lookahead = true, + keymaps = { + ["ak"] = { query = "@block.outer", desc = "around block" }, + ["ik"] = { query = "@block.inner", desc = "inside block" }, + ["ac"] = { query = "@class.outer", desc = "around class" }, + ["ic"] = { query = "@class.inner", desc = "inside class" }, + ["a?"] = { query = "@conditional.outer", desc = "around conditional" }, + ["i?"] = { query = "@conditional.inner", desc = "inside conditional" }, + ["af"] = { query = "@function.outer", desc = "around function " }, + ["if"] = { query = "@function.inner", desc = "inside function " }, + ["al"] = { query = "@loop.outer", desc = "around loop" }, + ["il"] = { query = "@loop.inner", desc = "inside loop" }, + ["aa"] = { query = "@parameter.outer", desc = "around argument" }, + ["ia"] = { query = "@parameter.inner", desc = "inside argument" }, + }, + }, + move = { + enable = true, + set_jumps = true, + goto_next_start = { + ["]k"] = { query = "@block.outer", desc = "Next block start" }, + ["]f"] = { query = "@function.outer", desc = "Next function start" }, + ["]a"] = { query = "@parameter.inner", desc = "Next parameter start" }, + }, + goto_next_end = { + ["]K"] = { query = "@block.outer", desc = "Next block end" }, + ["]F"] = { query = "@function.outer", desc = "Next function end" }, + ["]A"] = { query = "@parameter.inner", desc = "Next parameter end" }, + }, + goto_previous_start = { + ["[k"] = { query = "@block.outer", desc = "Previous block start" }, + ["[f"] = { query = "@function.outer", desc = "Previous function start" }, + ["[a"] = { query = "@parameter.inner", desc = "Previous parameter start" }, + }, + goto_previous_end = { + ["[K"] = { query = "@block.outer", desc = "Previous block end" }, + ["[F"] = { query = "@function.outer", desc = "Previous function end" }, + ["[A"] = { query = "@parameter.inner", desc = "Previous parameter end" }, + }, + }, + swap = { + enable = true, + swap_next = { + [">K"] = { query = "@block.outer", desc = "Swap next block" }, + [">F"] = { query = "@function.outer", desc = "Swap next function" }, + [">A"] = { query = "@parameter.inner", desc = "Swap next parameter" }, + }, + swap_previous = { + [""] = cmp.mapping.select_prev_item { + behavior = cmp.SelectBehavior.Select, + count = 8, + }, + [""] = cmp.mapping.select_next_item { + behavior = cmp.SelectBehavior.Select, + count = 8, + }, + [""] = cmp.mapping.select_prev_item { + behavior = cmp.SelectBehavior.Select, + count = 16, + }, + [""] = cmp.mapping.select_next_item { + behavior = cmp.SelectBehavior.Select, + count = 16, + }, + [""] = cmp.mapping.select_prev_item { + behavior = cmp.SelectBehavior.Select, + count = 16, + }, + [""] = cmp.mapping.select_next_item { + behavior = cmp.SelectBehavior.Select, + count = 16, + }, + [""] = cmp.mapping.select_prev_item { + behavior = cmp.SelectBehavior.Select, + }, + [""] = cmp.mapping.select_next_item { + behavior = cmp.SelectBehavior.Select, + }, + [""] = cmp.mapping.select_prev_item { + behavior = cmp.SelectBehavior.Insert, + }, + [""] = cmp.mapping.select_next_item { + behavior = cmp.SelectBehavior.Insert, + }, + [""] = cmp.mapping.select_prev_item { + behavior = cmp.SelectBehavior.Insert, + }, + [""] = cmp.mapping.select_next_item { + behavior = cmp.SelectBehavior.Insert, + }, + [""] = cmp.mapping(cmp.mapping.scroll_docs(-4), { "i", "c" }), + [""] = cmp.mapping(cmp.mapping.scroll_docs(4), { "i", "c" }), + [""] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }), + [""] = cmp.config.disable, + [""] = cmp.mapping { + i = cmp.mapping.abort(), + c = cmp.mapping.close(), + }, + [""] = cmp.mapping.confirm { select = false }, + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }, + sources = cmp.config.sources { + { name = "nvim_lsp", priority = 1000 }, + { name = "luasnip", priority = 750 }, + { name = "buffer", priority = 500 }, + { name = "path", priority = 250 }, + }, + } + end, + }, + +} diff --git a/dot_config/nvim/lua/plugins/4-dev.lua b/dot_config/nvim/lua/plugins/4-dev.lua new file mode 100644 index 0000000000000000000000000000000000000000..546bb95f7aaeb095dfb3154dfbeb83bafea35678 --- /dev/null +++ b/dot_config/nvim/lua/plugins/4-dev.lua @@ -0,0 +1,901 @@ +-- Dev +-- Things you actively use for coding. + +-- Sections: +-- ## SNIPPETS +-- -> luasnip [snippet engine] +-- -> friendly-snippets [snippet templates] + +-- ## GIT +-- -> gitsigns.nvim [git hunks] +-- -> fugitive.vim [git commands] + +-- ## ANALYZER +-- -> aerial.nvim [symbols tree] +-- -> litee-calltree.nvim [calltree] + +-- ## CODE DOCUMENTATION +-- -> dooku.nvim [html doc generator] +-- -> markdown-preview.nvim [markdown previewer] +-- -> markmap.nvim [markdown mindmap] + +-- ## ARTIFICIAL INTELLIGENCE +-- -> neural [chatgpt code generator] +-- -> copilot [github code suggestions] +-- -> guess-indent [guess-indent] + +-- ## COMPILER +-- -> compiler.nvim [compiler] +-- -> overseer.nvim [task runner] + +-- ## DEBUGGER +-- -> nvim-dap [debugger] + +-- ## TESTING +-- -> neotest.nvim [unit testing] +-- -> nvim-coverage [code coverage] + +-- ## LANGUAGE IMPROVEMENTS +-- -> guttentags_plus [auto generate C/C++ tags] + +local is_windows = vim.fn.has('win32') == 1 -- true if on windows + +return { + -- SNIPPETS ---------------------------------------------------------------- + -- Vim Snippets engine [snippet engine] + [snippet templates] + -- https://github.com/L3MON4D3/LuaSnip + -- https://github.com/rafamadriz/friendly-snippets + { + "L3MON4D3/LuaSnip", + build = not is_windows and "make install_jsregexp" or nil, + dependencies = { + "rafamadriz/friendly-snippets", + "zeioth/NormalSnippets", + "benfowler/telescope-luasnip.nvim", + }, + event = "User BaseFile", + opts = { + history = true, + delete_check_events = "TextChanged", + region_check_events = "CursorMoved", + }, + config = function(_, opts) + if opts then require("luasnip").config.setup(opts) end + vim.tbl_map( + function(type) require("luasnip.loaders.from_" .. type).lazy_load() end, + { "vscode", "snipmate", "lua" } + ) + -- friendly-snippets - enable standardized comments snippets + require("luasnip").filetype_extend("typescript", { "tsdoc" }) + require("luasnip").filetype_extend("javascript", { "jsdoc" }) + require("luasnip").filetype_extend("lua", { "luadoc" }) + require("luasnip").filetype_extend("python", { "pydoc" }) + require("luasnip").filetype_extend("rust", { "rustdoc" }) + require("luasnip").filetype_extend("cs", { "csharpdoc" }) + require("luasnip").filetype_extend("java", { "javadoc" }) + require("luasnip").filetype_extend("c", { "cdoc" }) + require("luasnip").filetype_extend("cpp", { "cppdoc" }) + require("luasnip").filetype_extend("php", { "phpdoc" }) + require("luasnip").filetype_extend("kotlin", { "kdoc" }) + require("luasnip").filetype_extend("ruby", { "rdoc" }) + require("luasnip").filetype_extend("sh", { "shelldoc" }) + end, + }, + + -- GIT --------------------------------------------------------------------- + -- Git signs [git hunks] + -- https://github.com/lewis6991/gitsigns.nvim + { + "lewis6991/gitsigns.nvim", + enabled = vim.fn.executable "git" == 1, + event = "User BaseGitFile", + opts = function() + local get_icon = require("base.utils").get_icon + return { + max_file_length = vim.g.big_file.lines, + signs = { + add = { text = get_icon("GitSign") }, + change = { text = get_icon("GitSign") }, + delete = { text = get_icon("GitSign") }, + topdelete = { text = get_icon("GitSign") }, + changedelete = { text = get_icon("GitSign") }, + untracked = { text = get_icon("GitSign") }, + }, + } + end + }, + + -- Git fugitive mergetool + [git commands] + -- https://github.com/lewis6991/gitsigns.nvim + -- PR needed: Setup keymappings to move quickly when using this feature. + -- + -- We only want this plugin to use it as mergetool like "git mergetool". + -- To enable this feature, add this to your global .gitconfig: + -- + -- [mergetool "fugitive"] + -- cmd = nvim -c \"Gvdiffsplit!\" \"$MERGED\" + -- [merge] + -- tool = fugitive + -- [mergetool] + -- keepBackup = false + { + "tpope/vim-fugitive", + enabled = vim.fn.executable "git" == 1, + dependencies = { "tpope/vim-rhubarb" }, + cmd = { + "Gvdiffsplit", + "Gdiffsplit", + "Gedit", + "Gsplit", + "Gread", + "Gwrite", + "Ggrep", + "GMove", + "GRename", + "GDelete", + "GRemove", + "GBrowse", + "Git", + "Gstatus", + }, + config = function() + -- NOTE: On vimplugins we use config instead of opts. + vim.g.fugitive_no_maps = 1 + end, + }, + + -- ANALYZER ---------------------------------------------------------------- + -- [symbols tree] + -- https://github.com/stevearc/aerial.nvim + { + "stevearc/aerial.nvim", + event = "User BaseFile", + opts = { + filter_kind = { -- Symbols that will appear on the tree + -- "Class", + "Constructor", + "Enum", + "Function", + "Interface", + -- "Module", + "Method", + -- "Struct", + }, + open_automatic = false, -- Open if the buffer is compatible + autojump = true, + link_folds_to_tree = false, + link_tree_to_folds = false, + attach_mode = "global", + backends = { "lsp", "treesitter", "markdown", "man" }, + disable_max_lines = vim.g.big_file.lines, + disable_max_size = vim.g.big_file.size, + layout = { + min_width = 28, + default_direction = "right", + placement = "edge", + }, + show_guides = true, + guides = { + mid_item = "├ ", + last_item = "└ ", + nested_top = "│ ", + whitespace = " ", + }, + keymaps = { + ["[y"] = "actions.prev", + ["]y"] = "actions.next", + ["[Y"] = "actions.prev_up", + ["]Y"] = "actions.next_up", + ["{"] = false, + ["}"] = false, + ["[["] = false, + ["]]"] = false, + }, + }, + config = function(_, opts) + require("aerial").setup(opts) + -- HACK: The first time you open aerial on a session, close all folds. + vim.api.nvim_create_autocmd({"FileType", "BufEnter"}, { + desc = "Aerial: When aerial is opened, close all its folds.", + callback = function() + local is_aerial = vim.bo.filetype == "aerial" + local is_ufo_available = require("base.utils").is_available("nvim-ufo") + if is_ufo_available and is_aerial and vim.b.new_aerial_session == nil then + vim.b.new_aerial_session = false + require("aerial").tree_set_collapse_level(0, 0) + end + end, + }) + end + }, + + -- Litee calltree [calltree] + -- https://github.com/ldelossa/litee.nvim + -- https://github.com/ldelossa/litee-calltree.nvim + -- press ? inside the panel to show help. + { + 'ldelossa/litee.nvim', + event = "User BaseFile", + opts = { + notify = { enabled = false }, + panel = { + orientation = "bottom", + panel_size = 10, + }, + }, + config = function(_, opts) + require('litee.lib').setup(opts) + end + }, + { + 'ldelossa/litee-calltree.nvim', + dependencies = 'ldelossa/litee.nvim', + event = "User BaseFile", + opts = { + on_open = "panel", -- or popout + map_resize_keys = false, + keymaps = { + expand = "", + collapse = "c", + collapse_all = "C", + jump = "" + }, + }, + config = function(_, opts) + require('litee.calltree').setup(opts) + + -- Highlight only while on calltree + vim.api.nvim_create_autocmd({ "WinEnter" }, { + desc = "Clear highlights when leaving calltree + UX improvements.", + callback = function() + vim.defer_fn(function() + if vim.bo.filetype == "calltree" then + vim.wo.colorcolumn = "0" + vim.wo.foldcolumn = "0" + vim.cmd("silent! PinBuffer") -- stickybuf.nvim + vim.cmd("silent! hi LTSymbolJump ctermfg=015 ctermbg=110 cterm=italic,bold,underline guifg=#464646 guibg=#87afd7 gui=italic,bold") + vim.cmd("silent! hi LTSymbolJumpRefs ctermfg=015 ctermbg=110 cterm=italic,bold,underline guifg=#464646 guibg=#87afd7 gui=italic,bold") + else + vim.cmd("silent! highlight clear LTSymbolJump") + vim.cmd("silent! highlight clear LTSymbolJumpRefs") + end + end, 100) + end + }) + end + }, + + -- CODE DOCUMENTATION ------------------------------------------------------ + -- dooku.nvim [html doc generator] + -- https://github.com/zeioth/dooku.nvim + { + "zeioth/dooku.nvim", + cmd = { + "DookuGenerate", + "DookuOpen", + "DookuAutoSetup" + }, + opts = {}, + }, + + -- [markdown previewer] + -- https://github.com/iamcco/markdown-preview.nvim + -- Note: If you change the build command, wipe ~/.local/data/nvim/lazy + { + "iamcco/markdown-preview.nvim", + build = function() vim.fn["mkdp#util#install"]() end, + ft = { "markdown" }, + cmd = { + "MarkdownPreview", + "MarkdownPreviewStop", + "MarkdownPreviewToggle", + }, + }, + + -- [markdown markmap] + -- https://github.com/zeioth/markmap.nvim + -- Important: Make sure you have yarn in your PATH before running markmap. + { + "zeioth/markmap.nvim", + build = "yarn global add markmap-cli", + cmd = { "MarkmapOpen", "MarkmapSave", "MarkmapWatch", "MarkmapWatchStop" }, + config = function(_, opts) require("markmap").setup(opts) end, + }, + + -- ARTIFICIAL INTELLIGENCE ------------------------------------------------- + -- neural [chatgpt code generator] + -- https://github.com/dense-analysis/neural + -- + -- NOTE: In order for this plugin to work, you will have to set + -- the next env var in your OS: + -- OPENAI_API_KEY="my_key_here" + { + "dense-analysis/neural", + cmd = { "Neural" }, + config = function() + require("neural").setup { + source = { + openai = { + api_key = vim.env.OPENAI_API_KEY, + }, + }, + ui = { + prompt_icon = ">", + }, + } + end, + }, + + -- copilot [github code suggestions] + -- https://github.com/github/copilot.vim + -- As alternative to chatgpt, you can use copilot uncommenting this. + -- Then you must run :Copilot setup + -- { + -- "github/copilot.vim", + -- event = "User BaseFile" + -- }, + -- copilot-cmp + -- https://github.com/zbirenbaum/copilot-cmp + -- { + -- "zbirenbaum/copilot-cmp", + -- opts = { suggesion = { enabled = false }, panel = { enabled = false } }, + -- config = function (_, opts) require("copilot_cmp").setup(opts) end + -- }, + + -- [guess-indent] + -- https://github.com/NMAC427/guess-indent.nvim + -- Note that this plugin won't autoformat the code. + -- It just set the buffer options to tabluate in a certain way. + { + "NMAC427/guess-indent.nvim", + event = "User BaseFile", + opts = {} + }, + + -- COMPILER ---------------------------------------------------------------- + -- compiler.nvim [compiler] + -- https://github.com/zeioth/compiler.nvim + { + "zeioth/compiler.nvim", + cmd = { + "CompilerOpen", + "CompilerToggleResults", + "CompilerRedo", + "CompilerStop" + }, + dependencies = { "stevearc/overseer.nvim" }, + opts = {}, + }, + + -- overseer [task runner] + -- https://github.com/stevearc/overseer.nvim + -- If you need to close a task immediately: + -- press ENTER in the output menu on the task you wanna close. + { + "stevearc/overseer.nvim", + cmd = { + "OverseerOpen", + "OverseerClose", + "OverseerToggle", + "OverseerSaveBundle", + "OverseerLoadBundle", + "OverseerDeleteBundle", + "OverseerRunCmd", + "OverseerRun", + "OverseerInfo", + "OverseerBuild", + "OverseerQuickAction", + "OverseerTaskAction", + "OverseerClearCache" + }, + opts = { + task_list = { -- the window that shows the results. + direction = "bottom", + min_height = 25, + max_height = 25, + default_detail = 1, + }, + -- component_aliases = { + -- default = { + -- -- Behaviors that will apply to all tasks. + -- "on_exit_set_status", -- don't delete this one. + -- "on_output_summarize", -- show last line on the list. + -- "display_duration", -- display duration. + -- "on_complete_notify", -- notify on task start. + -- "open_output", -- focus last executed task. + -- { "on_complete_dispose", timeout=300 }, -- dispose old tasks. + -- }, + -- }, + }, + }, + + -- DEBUGGER ---------------------------------------------------------------- + -- Debugger alternative to vim-inspector [debugger] + -- https://github.com/mfussenegger/nvim-dap + -- Here we configure the adapter+config of every debugger. + -- Debuggers don't have system dependencies, you just install them with mason. + -- We currently ship most of them with nvim. + { + "mfussenegger/nvim-dap", + enabled = vim.fn.has "win32" == 0, + event = "User BaseFile", + config = function() + local dap = require("dap") + + -- C# + dap.adapters.coreclr = { + type = 'executable', + command = vim.fn.stdpath('data') .. '/mason/bin/netcoredbg', + args = { '--interpreter=vscode' } + } + dap.configurations.cs = { + { + type = "coreclr", + name = "launch - netcoredbg", + request = "launch", + program = function() -- Ask the user what executable wants to debug + return vim.fn.input('Path to dll: ', vim.fn.getcwd() .. '/bin/Program.exe', 'file') + end, + }, + } + + -- F# + dap.configurations.fsharp = dap.configurations.cs + + -- Visual basic dotnet + dap.configurations.vb = dap.configurations.cs + + -- Java + -- Note: The java debugger jdtls is automatically spawned and configured + -- by the plugin 'nvim-java' in './3-dev-core.lua'. + + -- Python + dap.adapters.python = { + type = 'executable', + command = vim.fn.stdpath('data') .. '/mason/packages/debugpy/venv/bin/python', + args = { '-m', 'debugpy.adapter' }, + } + dap.configurations.python = { + { + type = "python", + request = "launch", + name = "Launch file", + program = "${file}", -- This configuration will launch the current file if used. + }, + } + + -- Lua + dap.adapters.nlua = function(callback, config) + callback({ type = 'server', host = config.host or "127.0.0.1", port = config.port or 8086 }) + end + dap.configurations.lua = { + { + type = 'nlua', + request = 'attach', + name = "Attach to running Neovim instance", + program = function() pcall(require "osv".launch({ port = 8086 })) end, + } + } + + -- C + dap.adapters.codelldb = { + type = 'server', + port = "${port}", + executable = { + command = vim.fn.stdpath('data') .. '/mason/bin/codelldb', + args = { "--port", "${port}" }, + detached = function() if is_windows then return false else return true end end, + } + } + dap.configurations.c = { + { + name = 'Launch', + type = 'codelldb', + request = 'launch', + program = function() -- Ask the user what executable wants to debug + return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/bin/program', 'file') + end, + cwd = '${workspaceFolder}', + stopOnEntry = false, + args = {}, + }, + } + + -- C++ + dap.configurations.cpp = dap.configurations.c + + -- Rust + dap.configurations.rust = { + { + name = 'Launch', + type = 'codelldb', + request = 'launch', + program = function() -- Ask the user what executable wants to debug + return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/bin/program', 'file') + end, + cwd = '${workspaceFolder}', + stopOnEntry = false, + args = {}, + initCommands = function() -- add rust types support (optional) + -- Find out where to look for the pretty printer Python module + local rustc_sysroot = vim.fn.trim(vim.fn.system('rustc --print sysroot')) + + local script_import = 'command script import "' .. rustc_sysroot .. '/lib/rustlib/etc/lldb_lookup.py"' + local commands_file = rustc_sysroot .. '/lib/rustlib/etc/lldb_commands' + + local commands = {} + local file = io.open(commands_file, 'r') + if file then + for line in file:lines() do + table.insert(commands, line) + end + file:close() + end + table.insert(commands, 1, script_import) + + return commands + end, + } + } + + -- Go + -- Requires: + -- * You have initialized your module with 'go mod init module_name'. + -- * You :cd your project before running DAP. + dap.adapters.delve = { + type = 'server', + port = '${port}', + executable = { + command = vim.fn.stdpath('data') .. '/mason/packages/delve/dlv', + args = { 'dap', '-l', '127.0.0.1:${port}' }, + } + } + dap.configurations.go = { + { + type = "delve", + name = "Compile module and debug this file", + request = "launch", + program = "./${relativeFileDirname}", + }, + { + type = "delve", + name = "Compile module and debug this file (test)", + request = "launch", + mode = "test", + program = "./${relativeFileDirname}" + }, + } + + -- Dart / Flutter + dap.adapters.dart = { + type = 'executable', + command = vim.fn.stdpath('data') .. '/mason/bin/dart-debug-adapter', + args = { 'dart' } + } + dap.adapters.flutter = { + type = 'executable', + command = vim.fn.stdpath('data') .. '/mason/bin/dart-debug-adapter', + args = { 'flutter' } + } + dap.configurations.dart = { + { + type = "dart", + request = "launch", + name = "Launch dart", + dartSdkPath = "/opt/flutter/bin/cache/dart-sdk/", -- ensure this is correct + flutterSdkPath = "/opt/flutter", -- ensure this is correct + program = "${workspaceFolder}/lib/main.dart", -- ensure this is correct + cwd = "${workspaceFolder}", + }, + { + type = "flutter", + request = "launch", + name = "Launch flutter", + dartSdkPath = "/opt/flutter/bin/cache/dart-sdk/", -- ensure this is correct + flutterSdkPath = "/opt/flutter", -- ensure this is correct + program = "${workspaceFolder}/lib/main.dart", -- ensure this is correct + cwd = "${workspaceFolder}", + } + } + + -- Kotlin + -- Kotlin projects have very weak project structure conventions. + -- You must manually specify what the project root and main class are. + dap.adapters.kotlin = { + type = 'executable', + command = vim.fn.stdpath('data') .. '/mason/bin/kotlin-debug-adapter', + } + dap.configurations.kotlin = { + { + type = 'kotlin', + request = 'launch', + name = 'Launch kotlin program', + projectRoot = "${workspaceFolder}/app", -- ensure this is correct + mainClass = "AppKt", -- ensure this is correct + }, + } + + -- Javascript / Typescript (firefox) + dap.adapters.firefox = { + type = 'executable', + command = vim.fn.stdpath('data') .. '/mason/bin/firefox-debug-adapter', + } + dap.configurations.typescript = { + { + name = 'Debug with Firefox', + type = 'firefox', + request = 'launch', + reAttach = true, + url = 'http://localhost:4200', -- Write the actual URL of your project. + webRoot = '${workspaceFolder}', + firefoxExecutable = '/usr/bin/firefox' + } + } + dap.configurations.javascript = dap.configurations.typescript + dap.configurations.javascriptreact = dap.configurations.typescript + dap.configurations.typescriptreact = dap.configurations.typescript + + -- Javascript / Typescript (chromium) + -- If you prefer to use this adapter, comment the firefox one. + -- But to use this adapter, you must manually run one of these two, first: + -- * chromium --remote-debugging-port=9222 --user-data-dir=remote-profile + -- * google-chrome-stable --remote-debugging-port=9222 --user-data-dir=remote-profile + -- After starting the debugger, you must manually reload page to get all features. + -- dap.adapters.chrome = { + -- type = 'executable', + -- command = vim.fn.stdpath('data')..'/mason/bin/chrome-debug-adapter', + -- } + -- dap.configurations.typescript = { + -- { + -- name = 'Debug with Chromium', + -- type = "chrome", + -- request = "attach", + -- program = "${file}", + -- cwd = vim.fn.getcwd(), + -- sourceMaps = true, + -- protocol = "inspector", + -- port = 9222, + -- webRoot = "${workspaceFolder}" + -- } + -- } + -- dap.configurations.javascript = dap.configurations.typescript + -- dap.configurations.javascriptreact = dap.configurations.typescript + -- dap.configurations.typescriptreact = dap.configurations.typescript + + -- PHP + dap.adapters.php = { + type = 'executable', + command = vim.fn.stdpath("data") .. '/mason/bin/php-debug-adapter', + } + dap.configurations.php = { + { + type = 'php', + request = 'launch', + name = 'Listen for Xdebug', + port = 9000 + } + } + + -- Shell + dap.adapters.bashdb = { + type = 'executable', + command = vim.fn.stdpath("data") .. '/mason/packages/bash-debug-adapter/bash-debug-adapter', + name = 'bashdb', + } + dap.configurations.sh = { + { + type = 'bashdb', + request = 'launch', + name = "Launch file", + showDebugOutput = true, + pathBashdb = vim.fn.stdpath("data") .. '/mason/packages/bash-debug-adapter/extension/bashdb_dir/bashdb', + pathBashdbLib = vim.fn.stdpath("data") .. '/mason/packages/bash-debug-adapter/extension/bashdb_dir', + trace = true, + file = "${file}", + program = "${file}", + cwd = '${workspaceFolder}', + pathCat = "cat", + pathBash = "/bin/bash", + pathMkfifo = "mkfifo", + pathPkill = "pkill", + args = {}, + env = {}, + terminalKind = "integrated", + } + } + + -- Elixir + dap.adapters.mix_task = { + type = 'executable', + command = vim.fn.stdpath("data") .. '/mason/bin/elixir-ls-debugger', + args = {} + } + dap.configurations.elixir = { + { + type = "mix_task", + name = "mix test", + task = 'test', + taskArgs = { "--trace" }, + request = "launch", + startApps = true, -- for Phoenix projects + projectDir = "${workspaceFolder}", + requireFiles = { + "test/**/test_helper.exs", + "test/**/*_test.exs" + } + }, + } + end, -- of dap config + dependencies = { + "rcarriga/nvim-dap-ui", + "rcarriga/cmp-dap", + "jay-babu/mason-nvim-dap.nvim", + "jbyuki/one-small-step-for-vimkind", + "nvim-java/nvim-java", + }, + }, + + -- nvim-dap-ui [dap ui] + -- https://github.com/mfussenegger/nvim-dap-ui + -- user interface for the debugger dap + { + "rcarriga/nvim-dap-ui", + dependencies = { "nvim-neotest/nvim-nio" }, + opts = { floating = { border = "rounded" } }, + config = function(_, opts) + local dap, dapui = require("dap"), require("dapui") + dap.listeners.after.event_initialized["dapui_config"] = function( + ) + dapui.open() + end + dap.listeners.before.event_terminated["dapui_config"] = function( + ) + dapui.close() + end + dap.listeners.before.event_exited["dapui_config"] = function() + dapui.close() + end + dapui.setup(opts) + end, + }, + + -- cmp-dap [dap autocomplete] + -- https://github.com/mfussenegger/cmp-dap + -- Enables autocomplete for the debugger dap. + { + "rcarriga/cmp-dap", + dependencies = { "nvim-cmp" }, + config = function() + require("cmp").setup.filetype( + { "dap-repl", "dapui_watches", "dapui_hover" }, + { + sources = { + { name = "dap" }, + }, + } + ) + end, + }, + + -- TESTING ----------------------------------------------------------------- + -- Run tests inside of nvim [unit testing] + -- https://github.com/nvim-neotest/neotest + -- + -- + -- MANUAL: + -- -- Unit testing: + -- To tun an unit test you can run any of these commands: + -- + -- :Neotest run -- Runs the nearest test to the cursor. + -- :Neotest stop -- Stop the nearest test to the cursor. + -- :Neotest run file -- Run all tests in the file. + -- + -- -- E2e and Test Suite + -- Normally you will prefer to open your e2e framework GUI outside of nvim. + -- But you have the next commands in ../base/3-autocmds.lua: + -- + -- :TestNodejs -- Run all tests for this nodejs project. + -- :TestNodejsE2e -- Run the e2e tests/suite for this nodejs project. + { + "nvim-neotest/neotest", + cmd = { "Neotest" }, + dependencies = { + "sidlatau/neotest-dart", + "Issafalcon/neotest-dotnet", + "jfpedroza/neotest-elixir", + "nvim-neotest/neotest-go", + "rcasia/neotest-java", + "nvim-neotest/neotest-jest", + "olimorris/neotest-phpunit", + "nvim-neotest/neotest-python", + "rouge8/neotest-rust", + "lawrence-laz/neotest-zig", + }, + opts = function() + return { + -- your neotest config here + adapters = { + require("neotest-dart"), + require("neotest-dotnet"), + require("neotest-elixir"), + require("neotest-go"), + require("neotest-java"), + require("neotest-jest"), + require("neotest-phpunit"), + require("neotest-python"), + require("neotest-rust"), + require("neotest-zig"), + }, + } + end, + config = function(_, opts) + -- get neotest namespace (api call creates or returns namespace) + local neotest_ns = vim.api.nvim_create_namespace "neotest" + vim.diagnostic.config({ + virtual_text = { + format = function(diagnostic) + local message = diagnostic.message:gsub("\n", " "):gsub("\t", " "):gsub("%s+", " "):gsub("^%s+", "") + return message + end, + }, + }, neotest_ns) + require("neotest").setup(opts) + end, + }, + + -- Shows a float panel with the [code coverage] + -- https://github.com/andythigpen/nvim-coverage + -- + -- Your project must generate coverage/lcov.info for this to work. + -- + -- On jest, make sure your packages.json file has this: + -- "tests": "jest --coverage" + -- + -- If you use other framework or language, refer to nvim-coverage docs: + -- https://github.com/andythigpen/nvim-coverage/blob/main/doc/nvim-coverage.txt + { + "zeioth/nvim-coverage", -- Our fork until all our PRs are merged. + cmd = { + "Coverage", + "CoverageLoad", + "CoverageLoadLcov", + "CoverageShow", + "CoverageHide", + "CoverageToggle", + "CoverageClear", + "CoverageSummary", + }, + dependencies = { "nvim-lua/plenary.nvim" }, + opts = { + summary = { + min_coverage = 80.0, -- passes if higher than + }, + }, + config = function(_, opts) require("coverage").setup(opts) end, + }, + + -- LANGUAGE IMPROVEMENTS ---------------------------------------------------- + -- guttentags_plus [auto generate C/C++ tags] + -- https://github.com/skywind3000/gutentags_plus + -- This plugin is necessary for using (go to ctag). + { + "skywind3000/gutentags_plus", + ft = { "c", "cpp" }, + dependencies = { "ludovicchabant/vim-gutentags" }, + config = function() + -- NOTE: On vimplugins we use config instead of opts. + vim.g.gutentags_plus_nomap = 1 + vim.g.gutentags_resolve_symlinks = 1 + vim.g.gutentags_cache_dir = vim.fn.stdpath "cache" .. "/tags" + vim.api.nvim_create_autocmd("FileType", { + desc = "Auto generate C/C++ tags", + callback = function() + local is_c = vim.bo.filetype == "c" or vim.bo.filetype == "cpp" + if is_c then vim.g.gutentags_enabled = 1 + else vim.g.gutentags_enabled = 0 end + end, + }) + end, + }, + +} -- end of return diff --git a/dot_config/polybar/config.ini.tmpl b/dot_config/polybar/config.ini.tmpl index e5d90b62881f1dabbdd2ec333c5c4521c1ae3b10..55ca444815fe3e4efb3de88e710477c1483dc939 100644 --- a/dot_config/polybar/config.ini.tmpl +++ b/dot_config/polybar/config.ini.tmpl @@ -1,11 +1,11 @@ [colors] background = ${xrdb:background} -background-alt = ${xrdb:color7} +background-alt = ${xrdb:color8} foreground = ${xrdb:foreground} foreground-alt = ${xrdb:color0} primary = ${xrdb:color1} secondary = ${xrdb:color11} -alert = ${xrdb:color3} +alert = ${xrdb:color11} [bar/top] width = 100% @@ -104,8 +104,8 @@ label-visible-padding = ${self.label-focused-padding} ; urgent = Workspace with urgency hint set label-urgent = %index% label-urgent-background = ${colors.alert} -label-urgent-foreground = ${colors.foreground-alt} -label-urgent-underline = ${colors.foreground} +label-urgent-foreground = ${colors.background} +label-urgent-underline = ${colors.alert} label-urgent-padding = 1 [module/mail] diff --git a/dot_config/private_zathura/zathurarc.tmpl b/dot_config/private_zathura/zathurarc.tmpl index 976f99b18199835af924d8ca053725e7de596723..8bc6618e2fefb05dc0bbae78ed0b9fd9ab8c07e7 100644 --- a/dot_config/private_zathura/zathurarc.tmpl +++ b/dot_config/private_zathura/zathurarc.tmpl @@ -6,43 +6,43 @@ set selection-clipboard "clipboard" {{- if eq .theme_variant "dark" }} -set default-fg "#CAD3F5" -set default-bg "#24273A" - -set completion-bg "#363A4F" -set completion-fg "#CAD3F5" -set completion-highlight-bg "#575268" -set completion-highlight-fg "#CAD3F5" -set completion-group-bg "#363A4F" -set completion-group-fg "#8AADF4" - -set statusbar-fg "#CAD3F5" -set statusbar-bg "#363A4F" - -set notification-bg "#363A4F" -set notification-fg "#CAD3F5" -set notification-error-bg "#363A4F" -set notification-error-fg "#ED8796" -set notification-warning-bg "#363A4F" -set notification-warning-fg "#FAE3B0" - -set inputbar-fg "#CAD3F5" -set inputbar-bg "#363A4F" - -set recolor-lightcolor "#24273A" -set recolor-darkcolor "#CAD3F5" - -set index-fg "#CAD3F5" -set index-bg "#24273A" -set index-active-fg "#CAD3F5" -set index-active-bg "#363A4F" - -set render-loading-bg "#24273A" -set render-loading-fg "#CAD3F5" - -set highlight-color "#575268" -set highlight-fg "#F5BDE6" -set highlight-active-color "#F5BDE6" +set default-fg "#d3c6aa" +set default-bg "#272e33" + +set completion-bg "#2e383c" +set completion-fg "#d3c6aa" +set completion-highlight-bg "#dbbc7f" +set completion-highlight-fg "#d3c6aa" +set completion-group-bg "#2e383c" +set completion-group-fg "#7fbbb3" + +set statusbar-fg "#d3c6aa" +set statusbar-bg "#2e383c" + +set notification-bg "#2e383c" +set notification-fg "#d3c6aa" +set notification-error-bg "#2e383c" +set notification-error-fg "#e67e80" +set notification-warning-bg "#2e383c" +set notification-warning-fg "#dbbc7f" + +set inputbar-fg "#d3c6aa" +set inputbar-bg "#2e383c" + +set recolor-lightcolor "#272e33" +set recolor-darkcolor "#d3c6aa" + +set index-fg "#d3c6aa" +set index-bg "#272e33" +set index-active-fg "#d3c6aa" +set index-active-bg "#2e383c" + +set render-loading-bg "#272e33" +set render-loading-fg "#d3c6aa" + +set highlight-color "#dbbc7f" +set highlight-fg "#d699b6" +set highlight-active-color "#d699b6" {{- end }} {{- if eq .theme_variant "light" }} set default-fg "#4C4F69" @@ -50,7 +50,7 @@ set default-bg "#EFF1F5" set completion-bg "#CCD0DA" set completion-fg "#4C4F69" -set completion-highlight-bg "#575268" +set completion-highlight-bg "#dbbc7f" set completion-highlight-fg "#4C4F69" set completion-group-bg "#CCD0DA" set completion-group-fg "#1E66F5" @@ -79,7 +79,7 @@ set index-active-bg "#CCD0DA" set render-loading-bg "#EFF1F5" set render-loading-fg "#4C4F69" -set highlight-color "#575268" +set highlight-color "#dbbc7f" set highlight-fg "#EA76CB" set highlight-active-color "#EA76CB" {{- end }} diff --git a/dot_config/zsh/private_dot_zshrc.tmpl b/dot_config/zsh/private_dot_zshrc.tmpl index e404912237bd21f7a4162694be3a3b0d1dd04844..2ac74884a314111ad839092ee382b80b510ac3fe 100644 --- a/dot_config/zsh/private_dot_zshrc.tmpl +++ b/dot_config/zsh/private_dot_zshrc.tmpl @@ -1,13 +1,13 @@ # Theming {{- if eq .theme_variant "dark" }} # https://github.com/catppuccin/zsh-syntax-highlighting -source ~/.config/zsh/themes/catppuccin-macchiato.zsh -export BAT_THEME="Catppuccin-macchiato" +source ~/.config/zsh/themes/everforest-hard-dark.zsh +export BAT_THEME="ansi" {{- end }} {{- if eq .theme_variant "light" }} # https://github.com/catppuccin/zsh-syntax-highlighting -source ~/.config/zsh/themes/catppuccin-latte.zsh -export BAT_THEME="Catppuccin-latte" +source ~/.config/zsh/themes/everforest-soft-light.zsh +export BAT_THEME="ansi" {{- end }} # Remove older command from the history if a duplicate is to be added. @@ -33,11 +33,10 @@ zstyle ':zim:termtitle:precmd' format '%1~' # Customize the style that the suggestions are shown with. # Set what highlighters will be used. # See https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters.md -ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets) +ZSH_HIGHLIGHT_HIGHLIGHTERS=(main cursor) # Customize the main highlighter styles. # See https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/main.md#how-to-tweak-it -#typeset -A ZSH_HIGHLIGHT_STYLES -#ZSH_HIGHLIGHT_STYLES[comment]='fg=242' +typeset -gA ZSH_HIGHLIGHT_STYLES # XDG variables export XDG_DATA_HOME="$HOME/.local/share" @@ -122,11 +121,13 @@ export PATH="$PATH:$CACHE/yay/distrobox/pkg/distrobox/usr/bin" export PATH="$PATH:$XDG_DATA_HOME/cargo/bin" export PATH="$PATH:$HOME/.radicle/bin" export PATH="$HOME/.local/bin:$PATH" +export PATH="$PATH:/usr/lib/kf6" +export PATH="$PATH:/usr/lib/kf5" # Additional preferences export LANG=en_GB.UTF-8 -export EDITOR='emacsclient -c' -export VISUAL='emacsclient -c' +export EDITOR='nvim' +export VISUAL='nvim' export _JAVA_AWT_WM_NONREPARENTING=1 export MANPAGER="nvim +Man!" export COLUMNS=80 @@ -163,6 +164,9 @@ source /usr/share/z/z.sh source /usr/share/fzf/key-bindings.zsh source /usr/share/fzf/completion.zsh +# Completions for git extras +source /usr/share/doc/git-extras/git-extras-completion.zsh + # Ranger conf export RANGER_LOAD_DEFAULT_RC=false @@ -177,7 +181,6 @@ alias u="linx-client" alias clip="xclip -selection clipboard" alias tmp="cd $(mktemp -d) && export TEMP=$(pwd)" alias send="rsync -amzzP" -alias tree="eza --tree" alias bat="bat -n --tabs 2" alias mov="joshuto ~/Bulk/Media/Movies" alias tv="joshuto ~/Bulk/Media/TV\ Shows" @@ -194,6 +197,7 @@ alias ac="aicommits" alias tc="turbocommit" alias ai="sgpt" alias k="klog" +alias ls="lsd" # Blog-related aliases alias secluded="cd ~/repos/personal/secluded && ./gen" diff --git a/dot_local/bin/executable_startup.tmpl b/dot_local/bin/executable_startup.tmpl index 02b8fbad035fb544d0928f558e5187b23043fcd2..c6921e04d8775d50ac396f1dfa3ff75c6ddf3a26 100644 --- a/dot_local/bin/executable_startup.tmpl +++ b/dot_local/bin/executable_startup.tmpl @@ -13,6 +13,7 @@ if [[ -n $WAYLAND_DISPLAY ]]; then hyprctl -i 0 dispatch exec -- "xfsettingsd" hyprctl -i 0 dispatch exec -- "dbus-update-activation-environment --all" hyprctl -i 0 dispatch exec -- "telegram-desktop" + hyprctl -i 0 dispatch exec -- "kdeconnect-indicator" {{- if eq .chezmoi.hostname "angmar" }} hyprctl -i 0 dispatch exec -- "caddy start --adapter caddyfile --config ~/Bulk/Media/Caddyfile" hyprctl -i 0 dispatch exec -- "firefox-developer-edition" @@ -37,6 +38,7 @@ else i3-msg exec "xrdb -load ~/.Xresources" i3-msg exec "xfsettingsd" i3-msg exec "dbus-update-activation-environment --all" + i3-msg exec "kdeconnect-indicator" {{- if eq .chezmoi.hostname "angmar" }} i3-msg exec "caddy start --adapter caddyfile --config ~/Bulk/Media/Caddyfile" i3-msg workspace 7 diff --git a/dot_local/share/dark-mode.d/executable_swap.sh b/dot_local/share/dark-mode.d/executable_swap.sh index 2615f91abba341e54a90332f1a67273431008305..f649ffa39b9d2ba1a36c1d015faa71fb7238055a 100644 --- a/dot_local/share/dark-mode.d/executable_swap.sh +++ b/dot_local/share/dark-mode.d/executable_swap.sh @@ -3,6 +3,9 @@ sed -i 's/light/dark/g' ~/.config/chezmoi/chezmoi.toml chezmoi apply xfconf-query -c xsettings -p /Net/ThemeName -s "Everforest-Dark" +xfconf-query -c xsettings -p /Net/IconThemeName -s "Everforest-Dark" +gsettings set org.gnome.desktop.interface gtk-theme "Everforest-Dark" +gsettings set org.gnome.desktop.interface icon-theme "Everforest-Dark" gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' xrdb -load ~/.Xresources "$XDG_CONFIG_HOME/emacs/bin/doom" sync @@ -23,6 +26,6 @@ else fi unlink ~/.wallpaper.png -ln -s ~/Pictures/walls/everforest-dark.png ~/.wallpaper.png +ln -s ~/Pictures/walls/everforest-hard-dark.png ~/.wallpaper.png feh --bg-scale ~/.wallpaper.png notify-send "Theme switch complete" diff --git a/dot_local/share/light-mode.d/executable_swap.sh b/dot_local/share/light-mode.d/executable_swap.sh index 7fac827cfb5746d4d19faeba14b20b9578202e14..82b6c69d4d8f362ab169d7d2f4530222a0b99b97 100644 --- a/dot_local/share/light-mode.d/executable_swap.sh +++ b/dot_local/share/light-mode.d/executable_swap.sh @@ -3,6 +3,9 @@ sed -i 's/dark/light/g' ~/.config/chezmoi/chezmoi.toml chezmoi apply xfconf-query -c xsettings -p /Net/ThemeName -s "Everforest-Light-Soft" +xfconf-query -c xsettings -p /Net/IconThemeName -s "Everforest-Light" +gsettings set org.gnome.desktop.interface gtk-theme "Everforest-Light-Soft" +gsettings set org.gnome.desktop.interface icon-theme "Everforest-Light" gsettings set org.gnome.desktop.interface color-scheme 'prefer-light' xrdb -load ~/.Xresources "$XDG_CONFIG_HOME/emacs/bin/doom" sync @@ -23,6 +26,6 @@ else fi unlink ~/.wallpaper.png -ln -s ~/Pictures/walls/everforest-light.png ~/.wallpaper.png +ln -s ~/Pictures/walls/everforest-soft-light.png ~/.wallpaper.png feh --bg-scale ~/.wallpaper.png notify-send "Theme switch complete" diff --git a/private_dot_ssh/encrypted_config.tmpl.age b/private_dot_ssh/encrypted_config.tmpl.age index 0462a2c72f780d335a98f62f1885b8fb6f67f7f3..5873ed3122f770089c1245d3b007a44d27a77fd0 100644 --- a/private_dot_ssh/encrypted_config.tmpl.age +++ b/private_dot_ssh/encrypted_config.tmpl.age @@ -1,43 +1,42 @@ -----BEGIN AGE ENCRYPTED FILE----- -YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IEhBV2NqUSBBM0FHalZP -VTZOR1Q0THYrZmZwaER2ZkpCK0RNY0thNmtwVXdzb1ppSWFpMgpJRkdYVVVCSEN0 -Y1dsNkRDWVAvUlc1R3M1dmJodFRrNk9SV3B1azhGTFZRCi0+IHBpdi1wMjU2IHBE -YXpSZyBBcFZLdFJpM2pmaGQrVWZ1MkdNZWlqeVQ2RU90Yk9IRW4vK2V5RnBrWTJB -RQp3QUR0aFBvWERzdHJlTEIvTHVEb2wzOERlS0Izdy9UcU81SnVmVlVsQXZJCi0+ -IEtUdVkyLWdyZWFzZSBFJ2kgPSJ+ZmYxIEFyfEY1CjZaN29VelNjN0Mzem1lRVAv -NTVBVFJLTFd5V1hqVGZtQmovbUJSUXFrWXpUdXZ6WFZGa2JrN1kya1ZrTnhhSTcK -djdwR3NtUmdiamw2SE1nZEFrWG5XU3dtUGFPWnVBCi0tLSBGNUI4U094TmxMTFlW -OXVac3FmcGFCQ0JnTTc0V3lvcE9mcFFxZkI1SWI0CvCj9INWMTXsV7Qjkwx3qDi5 -TYMUxhSt4tLIxnqrlCiMu/u7yYkXh+Xb/GRng3Nlptp357mRkXn/sM7Rtm2qeki+ -zX9MUiFOUzX+FsqKQ3rOfU9AIBQjkC8Y0ZbTjn17c+/itoh4gV+boCQsdVcTzLLM -nQeByWkLnxjq0B97brgCCXUuPP7Lzu88kOzCp+I/KmVgSNj1o2LSWFM6B7Ptofgb -o/L25xjXSM0XYqnZeAeNZAWfkvpJ/arXUtzMEVSqGMWSvBZQ51On3zrKDkQThUc1 -2bIVs+FVfYJQCyhuUweMbWqyyU+Ru4HbeH4WA9pTqhHsUJi1ZU5wAlyX7ezUyLZU -y39CEU1wLamNzVeZwbhQv9DbrmHMnOl9tHpzX518hA50FGt9294TSzB2CcPSAjYA -SKfqZgOxdF8DdJuqBj0O5rJ9tEXPHkUI+TkyOcnpln8yVyUHM/wpOMpgsS8bfDPL -8o/J7wg56FfHsy1F72QyhMQsyquPWCHtmCXncHVWwlXE5pxeCazdcn4TVSPXs+Fq -yLYepyYhodQNNBJvfUvRN7BUkf2OTAZQGI8VMo9nibdpnfRxZrcp7wJcxJ06va/C -JYy2gkKbKa98pUr7ToCqaxDiPe6r8MIuYJ+MaW3imvEF/4b+DO3BrYBdPEaA/uH4 -EB8X20Eq5e3h37iDZAh6l9I++sJlyTRD+rjd9z3wc8bP7mhsbGsI+OzVK82J8ha2 -yBLo9XLpt3m691RDxEeUtugDpunEPhf6Woak8ErwUZcJ0rMQ9khLstzCFoehKeqV -Ffh8yXz8D/ZPWxY1OdxzVQ8Bd3JxYZlmjRTAbQL/yLZg0PBqFr0Ny2aBxfoGYLMB -NpzwX4uUCPbyK2g3tNHafL1YDIitEEiobYVnnhVIbJQqMhS/gsVW2daMNvJ/3KZu -1K3azW4t305/ryddRUBZ/ezJx/mf1Tr9xxnb9aj3MsvyhjbExFjUkx8/vEtnDZuA -9IPlsD0+ydoEA+IGJqepox3Sabl6x9e3ya2maa+1TF2K3h4mVQNp09yOrBhl1Eyr -V3eMWZe58nbFOdn8Aq99Ru0RkMesvvFAsAsKcwwuemLFNzdrl89Juuhr0dzXtMZu -GIX09i5bL60rZXl6RQx6rWoT28ir9yaYHZYqoEXlm4IZOEo0Bc3yKWATw0chpdvX -qlmz28gudJOBfvgfybC4SO7rD2g5vD+YRrhRQ7YOqQAuq6BcnSfUYilLC2PoBSCx -HipZ3cZvQSoqZ1D3R7mSZI1Rh9O6GZlU6UgXxrK0RBAqPL62APN8nlMyisXlt7KM -zwwDozt35qXSVf0ZgiDUTRwlfsUn6W+aJOsZasnLdIJDN0Y6nz4092brzMoz1ZIy -xAM9Gt772DDmOsgb2pDZ8YAQzO+3/U1/v/ikF/g9DZxLN+xQbT9zGJ1yrScvKS04 -7kny+e2cB6ye7iUafCsM0HzKg0b+NFyHqADeWO1MxJQYO8VjK3wbedbJ6pJ+9MRj -rjRt1ZwD2dCYphynYhpcy2CtImR4ngOMqoRtQEFTXcWafig1itkOnqYmLsy5dEH9 -YuOFeIyme9vwVvrh4WcOeSVnZOVExvEiKAkRageYCmL51BR+w92nuXBwzvhP6RM5 -KILstftZh8auNuEmDw9hK+FbOOSjJNSkkI8DKw5rTyvlVpGXxf7NYHMeYRkDFQfr -C3be+qzGocb9GOcFGiMp4W48xkUMwrn2YTaWACFawOEdtlyfUPIjFhEQCdu4CZ0p -lERNyo91DpcFLA6YqYUusJdrDd1988wzFURBMkas6tPCTZuuzj1lcvqhW/g2kKOT -PrAx4ftx7qbdWzoZ+VMY9U/R9knnO+xnQ8kmp+zAcc08N6ycNcrGGsJF/LC49cpA -m/282hpCQbUCgRxch+2uNH7IK0uos/b4Ee6ubrxNYXCSZKqtIYr4Vq8PjNumdQq7 -bSTVWNXGT54FmKhmSglMje8ANDGQM+aAiNbbip+GOiQAg6h7elFhY0uuUbb8k0ZV -XRlXO2pKlUaTY7XCdh28ZimCnfsinjRepNkgnR8YR2ETsPTXVkJ/SU8+KPRe +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IEhBV2NqUSBBOSs0ZzhD +d3RyKzZYekU5ckRNUDVzVVNtc2FpeEx5a0FsNEJGaXBvakVzUApndWMwSEFkSTYz +SUdRL3JMZnFwbGR6dFczT2tVd050VitUWkpZWlh6cVlBCi0+IHBpdi1wMjU2IHBE +YXpSZyBBa0RkZi9uZ1ZxUmdrZEpKWEhLZGQ4SkdGVTBteDY4SzRRRUY2aStIZllP +Vgp4cDZjenZReG1ubHNRdVdPWWhxM1NoUlBwQW5EZmhmeFdqdTdUWFBNKzNvCi0+ +IDd6aTBCPUEtZ3JlYXNlIHIqKW5vSicgS1pITGBSTSBZPyA/Ci9JMEw5YXhzQVRE +ci9HZUpQUG0xSUdTQkJCQmd2M2ppeWFpTVVTc3JnSkVYd1h1NWhVaTcvcXRTQWlo +eUJXN1MKZU9aL2IwUmNGR2I2NmRyd1hSNjhKdWJxY0EKLS0tIDJSUUx3MTRhL1Bo +bVJaUUs0UTNaYkd6RE5GVTR4MUcwcS9GVERZVnllUXMKjy5S2mub3DsSJyQZJ3nG +uqjR0xoW7xn/gd6tuwNunc6cCtpspp4QU//lNnARl3urpzTlLPbisadhNBKG7+i4 +Y65e6J7Zh/UyBf09VNCVnA4cV2jCB/jPARwXZyxAjyFzCeP6ze7Qsca9dzx6EazA +I1ocbPPDdNOHzcwq0nGec4N5H9DBTOK9sAveNsXw1e3KMy2BO/WO27iEIFthDkPR +ve4zQZogbhNfDH3oP98roYVBOufn7u+iV+Kye60MyAjorF3BG+BqViLm9KPJQjO+ +a4yCcxNitdBsN/SJ+e7pPNtfXbdzNgmjRyHgjOQMa4D/dCwbNSawFbQtWOTXh5KG +kABrOEBsiSYH4pGSkpRCUUXmDwbtVpRRs75CoGb2b3mpmYmC3lDRweQ9iv7s0S18 +hi5piJO2PFx8xDUGqhJ1/WqCATs60Lsv99hgn6WolmJISeSqmUa1Y7GAgmVwCs3K +GsiYZ1olzXgDAaAv3N//no9kGOnoJ3BnJl3fezuzljmKYLFtOfGNxwmOamrOeZfo +wMKKZrDM2daoy2HkhbFCeXzqDNbZ0HQk8IFo+tvFbQqx3rijD0/YKiTgCEgIscyh +a9z7DQ8AhpyaD3QX4FShi3mfnB89Apa87n7GdTWRhSqtH1GGd4l2n/kNm02E9B5q +o0Q43y3xo8lTm3xbN4DX4J9kFQC0H8zzcvqkmZT7OJMb2YypnKMnm1Dl/0OImQVG +jIhx7Dc2EpDlf2MBuQ+AUYseUAp18MdT1HlpOMzjrd15+k4vyBkXrWiFUudNf3+Q +YGN3aHGA/TYtfbjKAGFhaMR87RlC4jKa9aL2FN8iiys0MAkl+WoWh/5P7hnLkZln +WTAaayUxTqm7GhDjxR8uK+kqkbJMvyOvXhEL79PnkkO58lZDM/CiNSMF+Z5YPT1m +R6K+p0mZnszn2zf+dgxVnmlYl09nEGW0PX8sdDQ9BG83jdQl27/q0pb6T8lPdbBB +UbNarEaj2QGLrE/v0ZAPXf4lnMoOieKDvN8kCr7+gj7Agtn0pIZJydNQuokP4UMj +fFTqzZgpec3w2Tmne63wcOI8ZhpP2itfQlU8Bee/qrQrZd4mJgs89qF2zRdWiw9h +n60mOZIi+1j5QG2HdZzU9fzOgi7EulRj4VRf1Z3hNUehqUQYtRSEgGLyoSExO9TB +X+2LBJOqs0tTUTT8bdzPXJ+XlmmAB951g9nKPFWa4VaZQfGk5iYrlYT20Ontl09a +yiTbYTWLdl+AB6yJBM5P6guYpjzg3wvtcvGkuW+UsDI70GsyauwTo+OHN5UeTloZ +ZYVdyOHnT7WcrzanrXylb+wLP9Y5wDj+0JL2qdZpAzNUA/PNBVJzmY8qDltq/f7D +iUHUYEzSNJArwGrYQUd8Mubx8Rt1PUmWLJBcv6NV9hyClq6WiuXUmpaOoMjNpTiA +2pfzb2svjrdC9anFah1k7KDhrPkzhB5ld/o4b5mnqWGtRSVIETSZPr0wXsD2N05N +fe5BeE3+5YOd6xFj3Nt7Xa1ZHfgR1Gt4Nqhlx9MpNpmK7EqLIDPeyfd5QdK1kHD2 +RXGe44aRs3qI7JqrDjbHq3lJCfhjm4PR1uDZa7tGfQ23R/MUHhIumpAEhJWJ3BKB +se7hb+2EGTaHNII3BQogpVPg8X/qzZ1sHMiy0mLcg/Mv64+1FELczmjSAUKnDPj0 +cRuJEkr1/CBMiQc28/PIj6PVeNB2J8d+wWa5Yoy0mgo2lAm+MznKdTP4OSKQtixt +sedAX/RR9tHgZSYvNDIbt6XqKkV3ROFxuaaRpvyXKOG45Rcg2D1DjijOLrBHmIdu +FUCsh1VY10D8D0h8sEib0/wr2BoEpNv7eEse4QVI78GABrDUG3awBHa3XewY92mg +x15Q731cNt88PmOxLIl56hfXr+VJuMAffOYvyQ8ZqsdmmOzpJmojc1uFuavUBiV/ +WUSwjlRyPb27vpr5eATwY6ZjJwpJ5tfbid8KFWubuQ== -----END AGE ENCRYPTED FILE-----