Created
December 12, 2025 00:23
-
-
Save guinslym/8c71fc0d3d2da02d7e59106189e40329 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- =================================================== | |
| -- Leader key (must be set before lazy.nvim) | |
| -- =================================================== | |
| vim.g.mapleader = ' ' -- Set leader to spacebar | |
| vim.g.maplocalleader = ' ' | |
| -- =================================================== | |
| -- Lazy.nvim bootstrap | |
| -- =================================================== | |
| local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' | |
| if not vim.loop.fs_stat(lazypath) then | |
| local lazy_repo = 'https://github.com/folke/lazy.nvim.git' | |
| local out = vim.fn.system { | |
| 'git', | |
| 'clone', | |
| '--filter=blob:none', | |
| '--branch=stable', | |
| lazy_repo, | |
| lazypath | |
| } | |
| if vim.v.shell_error ~= 0 then | |
| error('Error cloning lazy.nvim:\n' .. out) | |
| end | |
| end | |
| vim.opt.rtp:prepend(lazypath) | |
| -- =================================================== | |
| -- Plugins Setup | |
| -- =================================================== | |
| require('lazy').setup({ | |
| -- Neo-tree file explorer | |
| { | |
| "nvim-neo-tree/neo-tree.nvim", | |
| branch = "v3.x", | |
| dependencies = { | |
| "nvim-lua/plenary.nvim", | |
| "MunifTanjim/nui.nvim", | |
| "nvim-tree/nvim-web-devicons", | |
| }, | |
| }, | |
| -- Treesitter (MUST be installed for Neogen to work) | |
| { | |
| "nvim-treesitter/nvim-treesitter", | |
| build = ":TSUpdate", | |
| config = function() | |
| require'nvim-treesitter.configs'.setup { | |
| ensure_installed = { "lua", "python", "javascript", "markdown", "json" }, | |
| sync_install = false, | |
| auto_install = true, | |
| highlight = { | |
| enable = true, | |
| additional_vim_regex_highlighting = false, | |
| }, | |
| indent = { enable = true }, | |
| } | |
| end | |
| }, | |
| -- Autocomplete engine | |
| { | |
| "hrsh7th/nvim-cmp", | |
| dependencies = { | |
| "hrsh7th/cmp-nvim-lsp", | |
| "hrsh7th/cmp-buffer", | |
| "hrsh7th/cmp-path", | |
| "hrsh7th/cmp-nvim-lua", | |
| "L3MON4D3/LuaSnip", | |
| "saadparwaiz1/cmp_luasnip", | |
| }, | |
| config = function() | |
| local cmp = require("cmp") | |
| local luasnip = require("luasnip") | |
| cmp.setup({ | |
| snippet = { | |
| expand = function(args) | |
| luasnip.lsp_expand(args.body) | |
| end, | |
| }, | |
| mapping = cmp.mapping.preset.insert({ | |
| -- Trigger completion menu | |
| ['<C-Space>'] = cmp.mapping.complete(), | |
| -- Navigate through completion items | |
| ['<C-n>'] = cmp.mapping.select_next_item(), | |
| ['<C-p>'] = cmp.mapping.select_prev_item(), | |
| -- Scroll docs | |
| ['<C-d>'] = cmp.mapping.scroll_docs(-4), | |
| ['<C-f>'] = cmp.mapping.scroll_docs(4), | |
| -- Confirm selection with Enter | |
| ['<CR>'] = cmp.mapping.confirm({ | |
| behavior = cmp.ConfirmBehavior.Replace, | |
| select = true | |
| }), | |
| -- Tab to confirm or jump to next snippet placeholder | |
| ['<Tab>'] = cmp.mapping(function(fallback) | |
| if cmp.visible() then | |
| cmp.confirm({ select = true }) | |
| elseif luasnip.expand_or_jumpable() then | |
| luasnip.expand_or_jump() | |
| else | |
| fallback() | |
| end | |
| end, { 'i', 's' }), | |
| -- Shift-Tab to jump to previous snippet placeholder | |
| ['<S-Tab>'] = cmp.mapping(function(fallback) | |
| if 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 }, | |
| }), | |
| completion = { | |
| completeopt = 'menu,menuone,noinsert', | |
| autocomplete = { | |
| cmp.TriggerEvent.TextChanged, | |
| }, | |
| }, | |
| experimental = { | |
| ghost_text = true, | |
| }, | |
| }) | |
| end | |
| }, | |
| -- Docstring generator | |
| { | |
| "danymat/neogen", | |
| dependencies = { | |
| "nvim-treesitter/nvim-treesitter", | |
| "L3MON4D3/LuaSnip", | |
| }, | |
| config = function() | |
| local neogen = require('neogen') | |
| neogen.setup({ | |
| enabled = true, | |
| snippet_engine = "luasnip", | |
| }) | |
| end, | |
| }, | |
| -- Function signature help | |
| { | |
| "ray-x/lsp_signature.nvim", | |
| config = function() | |
| require("lsp_signature").setup({ | |
| bind = true, | |
| hint_enable = true, | |
| floating_window = true, | |
| }) | |
| end | |
| }, | |
| -- Telescope fuzzy finder | |
| { | |
| "nvim-telescope/telescope.nvim", | |
| dependencies = { "nvim-lua/plenary.nvim" }, | |
| config = function() | |
| require('telescope').setup{} | |
| end, | |
| }, | |
| -- Auto-formatter | |
| { | |
| "stevearc/conform.nvim", | |
| config = function() | |
| require("conform").setup({ | |
| formatters_by_filetype = { | |
| python = { "black", "isort" }, | |
| }, | |
| format_on_save = { | |
| timeout_ms = 500, | |
| lsp_fallback = true, | |
| }, | |
| }) | |
| end, | |
| }, | |
| -- Git signs in the gutter | |
| { | |
| "lewis6991/gitsigns.nvim", | |
| config = function() | |
| require('gitsigns').setup() | |
| end, | |
| }, | |
| -- Git interface | |
| { | |
| "tpope/vim-fugitive", | |
| }, | |
| -- Toggle terminal | |
| { | |
| "akinsho/toggleterm.nvim", | |
| version = "*", | |
| config = function() | |
| require("toggleterm").setup({ | |
| direction = 'horizontal', | |
| size = 15, | |
| }) | |
| end, | |
| }, | |
| -- Easy commenting | |
| { | |
| "numToStr/Comment.nvim", | |
| config = function() | |
| require('Comment').setup() | |
| end, | |
| }, | |
| -- Auto-close brackets | |
| { | |
| "windwp/nvim-autopairs", | |
| config = function() | |
| require("nvim-autopairs").setup{} | |
| local cmp_autopairs = require('nvim-autopairs.completion.cmp') | |
| local cmp = require('cmp') | |
| cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done()) | |
| end, | |
| }, | |
| -- Indent guides | |
| { | |
| "lukas-reineke/indent-blankline.nvim", | |
| main = "ibl", | |
| config = function() | |
| require("ibl").setup() | |
| end, | |
| }, | |
| -- Better statusline | |
| { | |
| "nvim-lualine/lualine.nvim", | |
| dependencies = { "nvim-tree/nvim-web-devicons" }, | |
| config = function() | |
| require('lualine').setup({ | |
| options = { | |
| theme = 'auto', | |
| section_separators = '', | |
| component_separators = '|' | |
| } | |
| }) | |
| end, | |
| }, | |
| -- Color scheme | |
| { | |
| "catppuccin/nvim", | |
| name = "catppuccin", | |
| priority = 1000, | |
| config = function() | |
| vim.cmd.colorscheme "catppuccin-mocha" | |
| end, | |
| }, | |
| -- Which-key (shows keybindings) | |
| { | |
| "folke/which-key.nvim", | |
| config = function() | |
| require("which-key").setup() | |
| end, | |
| }, | |
| }) | |
| -- =================================================== | |
| -- Basic Settings | |
| -- =================================================== | |
| vim.opt.number = true | |
| vim.opt.relativenumber = true | |
| vim.opt.expandtab = true | |
| vim.opt.shiftwidth = 2 | |
| vim.opt.tabstop = 2 | |
| vim.opt.smartindent = true | |
| vim.opt.termguicolors = true | |
| -- Set completeopt for better completion experience | |
| vim.opt.completeopt = {'menu', 'menuone', 'noinsert'} | |
| -- =================================================== | |
| -- Clipboard Configuration (Fix OSC 52 issue) | |
| -- =================================================== | |
| vim.opt.clipboard = 'unnamedplus' -- Use system clipboard | |
| -- Disable OSC 52 which causes the paste hang | |
| vim.g.clipboard = { | |
| name = 'custom', | |
| copy = { | |
| ['+'] = {'xclip', '-selection', 'clipboard'}, | |
| ['*'] = {'xclip', '-selection', 'primary'}, | |
| }, | |
| paste = { | |
| ['+'] = {'xclip', '-selection', 'clipboard', '-o'}, | |
| ['*'] = {'xclip', '-selection', 'primary', '-o'}, | |
| }, | |
| cache_enabled = 0, | |
| } | |
| -- =================================================== | |
| -- Keymaps | |
| -- =================================================== | |
| -- File Explorer | |
| vim.keymap.set('n', '<leader>e', ':Neotree toggle<CR>', { noremap = true, silent = true, desc = 'Toggle file explorer' }) | |
| -- Telescope keymaps | |
| vim.keymap.set('n', '<leader>ff', '<cmd>Telescope find_files<cr>', { desc = 'Find files' }) | |
| vim.keymap.set('n', '<leader>fg', '<cmd>Telescope live_grep<cr>', { desc = 'Live grep' }) | |
| vim.keymap.set('n', '<leader>fb', '<cmd>Telescope buffers<cr>', { desc = 'Find buffers' }) | |
| vim.keymap.set('n', '<leader>fh', '<cmd>Telescope help_tags<cr>', { desc = 'Help tags' }) | |
| -- Terminal | |
| vim.keymap.set('n', '<leader>t', '<cmd>ToggleTerm<cr>', { desc = 'Toggle terminal' }) | |
| -- Format buffer | |
| vim.keymap.set('n', '<leader>f', function() | |
| require("conform").format({ async = true, lsp_fallback = true }) | |
| end, { desc = 'Format buffer' }) | |
| -- Git keymaps | |
| vim.keymap.set('n', '<leader>gs', '<cmd>Git<cr>', { desc = 'Git status' }) | |
| vim.keymap.set('n', '<leader>gb', '<cmd>Git blame<cr>', { desc = 'Git blame' }) | |
| vim.keymap.set('n', '<leader>gd', '<cmd>Gitsigns diffthis<cr>', { desc = 'Git diff' }) | |
| -- Generate docstring with Neogen - improved with error handling | |
| vim.keymap.set('n', '<leader>d', function() | |
| local ft = vim.bo.filetype | |
| if ft == "python" then | |
| local ok, neogen = pcall(require, 'neogen') | |
| if ok then | |
| local success, err = pcall(neogen.generate, { type = "func" }) | |
| if not success then | |
| print("Neogen error: " .. tostring(err)) | |
| print("Try running :TSUpdate python or :Lazy sync") | |
| end | |
| else | |
| print("Neogen not loaded. Run :Lazy sync") | |
| end | |
| else | |
| print("Neogen only configured for Python files") | |
| end | |
| end, { noremap = true, silent = false, desc = "Generate docstring" }) | |
| -- Alternative: generate for any type (function, class, type, file) | |
| vim.keymap.set('n', '<leader>da', function() | |
| require('neogen').generate() | |
| end, { noremap = true, silent = false, desc = "Generate annotation (auto-detect)" }) | |
| -- =================================================== | |
| -- Python LSP (pyright) using modern vim.lsp.config API | |
| -- =================================================== | |
| vim.lsp.config.pyright = { | |
| cmd = { 'pyright-langserver', '--stdio' }, | |
| filetypes = { 'python' }, | |
| root_markers = { 'pyproject.toml', 'setup.py', 'requirements.txt', '.git' }, | |
| settings = { | |
| python = { | |
| analysis = { | |
| autoSearchPaths = true, | |
| useLibraryCodeForTypes = true, | |
| diagnosticMode = "openFilesOnly", | |
| typeCheckingMode = "basic", | |
| } | |
| } | |
| }, | |
| } | |
| vim.api.nvim_create_autocmd('FileType', { | |
| pattern = 'python', | |
| callback = function(args) | |
| vim.lsp.enable('pyright') | |
| end, | |
| }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment