init.lua 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. -- disable netrw for nvim-tree plugin
  2. vim.g.loaded_netrw = 1
  3. vim.g.loaded_netrwPlugin = 1
  4. -- override stdpath locations, so that config is fully hermetic
  5. local orig_stdpath = vim.fn.stdpath
  6. vim.fn.stdpath = function(value)
  7. local config_path = orig_stdpath("config")
  8. if value == "config" then
  9. return config_path
  10. end
  11. if value == "data" then
  12. return config_path .. "/data"
  13. end
  14. if value == "cache" then
  15. return config_path .. "/cache"
  16. end
  17. if value == "state" then
  18. return config_path .. "/state"
  19. end
  20. return orig_stdpath(value)
  21. end
  22. -- package manager
  23. local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
  24. if not (vim.uv or vim.loop).fs_stat(lazypath) then
  25. local lazyrepo = "https://github.com/folke/lazy.nvim.git"
  26. local out = vim.fn.system({
  27. "git",
  28. "clone",
  29. "--filter=blob:none",
  30. "--branch=stable", -- latest stable release
  31. lazyrepo,
  32. lazypath,
  33. })
  34. if vim.v.shell_error ~= 0 then
  35. vim.api.nvim_echo({
  36. { "Failed to clone lazy.nvim:\n", "ErrorMsg" },
  37. { out, "WarningMsg" },
  38. { "\nPress any key to exit..." },
  39. }, true, {})
  40. vim.fn.getchar()
  41. os.exit(1)
  42. end
  43. end
  44. vim.opt.rtp:prepend(lazypath)
  45. -- set space key as a leader key,
  46. -- this has to be done before loading lazy.nvim
  47. vim.g.mapleader = ' '
  48. vim.g.maplocalleader = ' '
  49. require("lazy").setup({
  50. spec = {
  51. -- color theme
  52. {
  53. "catppuccin/nvim",
  54. name = "catppuccin",
  55. -- make sure to load this during startup
  56. lazy = false,
  57. -- make sure to load this beofre all other plugins
  58. priority = 1000,
  59. config = function()
  60. vim.cmd.colorscheme("catppuccin-macchiato")
  61. end,
  62. },
  63. "nvim-tree/nvim-tree.lua",
  64. "nvim-tree/nvim-web-devicons",
  65. "nvim-lualine/lualine.nvim",
  66. -- LSP
  67. {
  68. "mason-org/mason-lspconfig.nvim",
  69. opts = {
  70. ensure_installed = {
  71. "lua_ls",
  72. "rust_analyzer",
  73. "pyright",
  74. "clangd",
  75. },
  76. },
  77. dependencies = {
  78. { "mason-org/mason.nvim", opts = {} },
  79. "neovim/nvim-lspconfig",
  80. }
  81. },
  82. -- configure lua language server for nvim config file
  83. {
  84. "folke/lazydev.nvim",
  85. ft = "lua", -- only load for lua files
  86. opts = {},
  87. },
  88. -- venv selector for python
  89. {
  90. "linux-cultist/venv-selector.nvim",
  91. dependencies = {
  92. "neovim/nvim-lspconfig",
  93. {
  94. "nvim-telescope/telescope.nvim",
  95. branch = "0.1.x",
  96. dependencies = { "nvim-lua/plenary.nvim" }
  97. }, -- optional: you can also use fzf-lua, snacks, mini-pick instead.
  98. },
  99. ft = "python", -- Load when opening Python files
  100. keys = {
  101. { ",v", "<cmd>VenvSelect<cr>" }, -- Open picker on keymap
  102. },
  103. opts = { -- this can be an empty lua table - just showing below for clarity.
  104. search = {}, -- if you add your own searches, they go here.
  105. options = {} -- if you add plugin options, they go here.
  106. },
  107. },
  108. -- Autocompletion
  109. -- TODO: look into github.com/ms-jpq/coq_nvim
  110. {
  111. 'hrsh7th/nvim-cmp',
  112. dependencies = {
  113. -- Snippet Engine & its associated nvim-cmp source
  114. 'L3MON4D3/LuaSnip',
  115. 'saadparwaiz1/cmp_luasnip',
  116. -- Adds LSP completion capabilities
  117. 'hrsh7th/cmp-nvim-lsp',
  118. -- Adds a number of user-friendly snippets
  119. 'rafamadriz/friendly-snippets',
  120. },
  121. },
  122. -- Useful plugin to show you pending keybinds.
  123. "folke/which-key.nvim",
  124. -- "gc" to comment visual regions/lines
  125. "numToStr/Comment.nvim",
  126. -- Highlight, edit, and navigate code
  127. {
  128. 'nvim-treesitter/nvim-treesitter',
  129. lazy = false,
  130. build = ':TSUpdate',
  131. },
  132. -- Cut text without populating unnamed register
  133. {
  134. "gbprod/cutlass.nvim",
  135. opts = {
  136. cut_key = "<Leader>x",
  137. }
  138. },
  139. },
  140. -- automatically check for plugin updates
  141. checker = { enabled = true },
  142. })
  143. -- copy to system clipboard by default
  144. vim.o.clipboard = "unnamedplus"
  145. vim.o.termguicolors = true
  146. vim.o.completeopt = "menuone,noselect"
  147. vim.opt.guifont = "Hack Nerd Font Mono:h12"
  148. vim.opt.number = true
  149. vim.opt.mouse = ""
  150. vim.opt.hlsearch = true
  151. vim.opt.tabstop = 2
  152. vim.opt.shiftwidth = 2
  153. require("lualine").setup({})
  154. -- Configure Treesitter
  155. require('nvim-treesitter').install {
  156. 'haskell', 'c', 'cpp', 'go', 'glsl', 'lua', 'python', 'rust', 'tsx',
  157. 'typescript', 'javascript', 'vimdoc', 'vim', 'zig'
  158. }
  159. require("nvim-tree").setup({
  160. view = {
  161. width = 30,
  162. },
  163. on_attach = function (bufnr)
  164. local api = require "nvim-tree.api"
  165. --api.config.mappings.default_on_attach()
  166. api.map.on_attach.default(bufnr)
  167. vim.keymap.set("n", ".", api.tree.change_root_to_node,
  168. {noremap=true, silent=true, buffer=bufnr, nowait=true})
  169. end,
  170. })
  171. -- unmap space
  172. vim.api.nvim_set_keymap('n', '<Space>', '', {noremap=true, silent=true})
  173. -- window operations with leader key
  174. vim.api.nvim_set_keymap("n", "<Leader>w", "<C-w>", {noremap=true, silent=true})
  175. -- custom nvim tree mappings
  176. vim.api.nvim_set_keymap("n", "<Leader>ft", ":NvimTreeToggle<CR>", {noremap=true, silent=true})
  177. vim.api.nvim_set_keymap("n", "<BS>", ":NvimTreeFocus<CR>", {noremap=true, silent=true})
  178. -- Diagnostic keymaps
  179. vim.keymap.set('n', '<Leader>dp',
  180. function() vim.diagnostic.jump({count=-1, float=true}) end,
  181. { desc = 'Go to previous diagnostic message' })
  182. vim.keymap.set('n', '<Leader>dn',
  183. function() vim.diagnostic.jump({count=1, float=true}) end,
  184. { desc = 'Go to next diagnostic message' })
  185. vim.keymap.set('n', '<Leader>de', vim.diagnostic.open_float,
  186. { desc = 'Open floating diagnostic message' })
  187. vim.keymap.set('n', '<Leader>dl', vim.diagnostic.setloclist,
  188. { desc = 'Open diagnostics list' })
  189. -- nvim-cmp supports additional completion capabilities, so broadcast that to servers
  190. local capabilities = vim.lsp.protocol.make_client_capabilities()
  191. capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities)
  192. -- Configure autocompletion nvim-cmp
  193. -- See `:help cmp`
  194. local cmp = require 'cmp'
  195. local luasnip = require 'luasnip'
  196. require('luasnip.loaders.from_vscode').lazy_load()
  197. luasnip.config.setup {}
  198. cmp.setup {
  199. snippet = {
  200. expand = function(args)
  201. luasnip.lsp_expand(args.body)
  202. end,
  203. },
  204. mapping = cmp.mapping.preset.insert {
  205. ['<C-n>'] = cmp.mapping.select_next_item(),
  206. ['<C-p>'] = cmp.mapping.select_prev_item(),
  207. ['<C-d>'] = cmp.mapping.scroll_docs(-4),
  208. ['<C-f>'] = cmp.mapping.scroll_docs(4),
  209. ['<C-Space>'] = cmp.mapping.complete {},
  210. ['<CR>'] = cmp.mapping.confirm {
  211. behavior = cmp.ConfirmBehavior.Replace,
  212. select = true,
  213. },
  214. ['<Tab>'] = cmp.mapping(function(fallback)
  215. if cmp.visible() then
  216. cmp.select_next_item()
  217. elseif luasnip.expand_or_locally_jumpable() then
  218. luasnip.expand_or_jump()
  219. else
  220. fallback()
  221. end
  222. end, { 'i', 's' }),
  223. ['<S-Tab>'] = cmp.mapping(function(fallback)
  224. if cmp.visible() then
  225. cmp.select_prev_item()
  226. elseif luasnip.locally_jumpable(-1) then
  227. luasnip.jump(-1)
  228. else
  229. fallback()
  230. end
  231. end, { 'i', 's' }),
  232. },
  233. sources = {
  234. { name = 'nvim_lsp' },
  235. { name = 'luasnip' },
  236. },
  237. }
  238. -- Do not yank when pasting over selected text
  239. -- "x" - visual mode
  240. vim.keymap.set("x", "p", "P", { silent = true })
  241. -- Auto format selected code
  242. vim.keymap.set("v", "<leader>f", function()
  243. local start_pos = vim.api.nvim_buf_get_mark(0, "<")
  244. local end_pos = vim.api.nvim_buf_get_mark(0, ">")
  245. vim.lsp.buf.format({
  246. range = {
  247. ["start"] = { start_pos[1] - 1, start_pos[2] },
  248. ["end"] = { end_pos[1] - 1, end_pos[2] },
  249. },
  250. })
  251. end)