--[[ ===================================================================== ==================== READ THIS BEFORE CONTINUING ==================== ===================================================================== ======== .-----. ======== ======== .----------------------. | === | ======== ======== |.-""""""""""""""""""-.| |-----| ======== ======== || || | === | ======== ======== || KICKSTART.NVIM || |-----| ======== ======== || || | === | ======== ======== || || |-----| ======== ======== ||:Tutor || |:::::| ======== ======== |'-..................-'| |____o| ======== ======== `"")----------------(""` ___________ ======== ======== /::::::::::| |::::::::::\ \ no mouse \ ======== ======== /:::========| |==hjkl==:::\ \ required \ ======== ======== '""""""""""""' '""""""""""""' '""""""""""' ======== ======== ======== ===================================================================== ===================================================================== -- [[ Setting options ]] -- See `:help vim.o` -- Set to true if you have a Nerd Font installed and selected in the terminal vim.g.have_nerd_font = true -- Key mappings vim.g.mapleader = ' ' -- Set leader key to space vim.g.maplocalleader = ' ' -- Set local leader key (NEW) -- Make background transparent vim.api.nvim_set_hl(0, 'Normal', { bg = 'none' }) vim.api.nvim_set_hl(0, 'NormalNC', { bg = 'none' }) vim.api.nvim_set_hl(0, 'EndOfBuffer', { bg = 'none' }) vim.api.nvim_set_hl(0, 'SignColumn', { bg = 'none' }) -- Make sign column transparent vim.opt.number = true -- Line numbers -- Basic settings vim.opt.relativenumber = true -- Relative line numbers vim.opt.cursorline = true -- Highlight current line vim.opt.wrap = false -- Don't wrap lines vim.opt.scrolloff = 10 -- Keep 10 lines above/below cursor vim.opt.sidescrolloff = 8 -- Keep 8 columns left/right of cursor -- Indentation vim.opt.tabstop = 2 -- Tab width vim.opt.shiftwidth = 2 -- Indent width vim.opt.softtabstop = 2 -- Soft tab stop vim.opt.expandtab = true -- Use spaces instead of tabs vim.opt.smartindent = true -- Smart auto-indenting vim.opt.autoindent = true -- Copy indent from current line vim.o.breakindent = true -- Search settings vim.opt.ignorecase = true -- Case insensitive search vim.opt.smartcase = true -- Case sensitive if uppercase in search vim.opt.hlsearch = false -- Don't highlight search results vim.opt.incsearch = true -- Show matches as you type -- Visual settings vim.opt.termguicolors = true -- Enable 24-bit colors vim.opt.signcolumn = 'yes' -- Always show sign column vim.opt.showmatch = true -- Highlight matching brackets vim.opt.matchtime = 2 -- How long to show matching bracket vim.opt.cmdheight = 1 -- Command line height vim.opt.completeopt = 'menuone,noinsert,noselect' -- Completion options vim.opt.showmode = false -- Don't show mode in command line vim.opt.pumheight = 10 -- Popup menu height vim.opt.pumblend = 10 -- Popup menu transparency vim.opt.winblend = 0 -- Floating window transparency vim.opt.concealcursor = '' -- Don't hide cursor line markup vim.opt.conceallevel = 0 -- Don't hide markup -- vim.opt.lazyredraw = true -- Don't redraw during macros vim.opt.synmaxcol = 300 -- Syntax highlighting limit vim.o.winborder = 'rounded' -- Make floating windows have a rounded border vim.o.list = true vim.opt.listchars = { tab = ' ', trail = '·', nbsp = '␣' } -- Sets how whitespace chars will be displayed -- Folding settings vim.opt.foldmethod = 'expr' -- Use expression for folding -- vim.wo.vim.foldexpr = 'v:lua.vim.treesitter.foldexpr()' -- Use treesitter for folding vim.opt.foldlevel = 99 -- Start with all folds open -- File handling vim.opt.backup = false -- Don't create backup files vim.opt.writebackup = false -- Don't create backup before writing vim.opt.swapfile = false -- Don't create swap files vim.opt.undofile = true -- Persistent undo vim.o.undofile = true -- Save undo history vim.opt.undodir = vim.fn.expand '~/.vim/undodir' -- Undo directory vim.opt.updatetime = 250 -- Faster completion vim.opt.timeoutlen = 500 -- Key timeout duration vim.opt.ttimeoutlen = 0 -- Key code timeout vim.opt.autoread = true -- Auto reload files changed outside vim vim.opt.autowrite = false -- Don't auto save -- Behavior settings vim.opt.hidden = true -- Allow hidden buffers vim.opt.errorbells = false -- No error bells vim.opt.backspace = 'indent,eol,start' -- Better backspace behavior vim.opt.autochdir = false -- Don't auto change directory vim.opt.iskeyword:append '-' -- Treat dash as part of word vim.opt.path:append '**' -- include subdirectories in search vim.opt.selection = 'exclusive' -- Selection behavior vim.opt.mouse = 'a' -- Enable mouse support vim.opt.clipboard:append 'unnamedplus' -- Use system clipboard vim.opt.modifiable = true -- Allow buffer modifications vim.opt.encoding = 'UTF-8' -- Set encoding vim.opt.splitbelow = true -- Horizontal splits go below vim.opt.splitright = true -- Vertical splits go right vim.o.inccommand = 'split' vim.o.confirm = true -- Ask before closing (unsaved changes) -- Sync clipboard between OS and Neovim. -- Schedule the setting after `UiEnter` because it can increase startup-time. -- Remove this option if you want your OS clipboard to remain independent. -- See `:help 'clipboard'` vim.schedule(function() vim.o.clipboard = 'unnamedplus' end) -- Don't show the mode, since it's already in the status line vim.o.showmode = false -- [[ Basic Keymaps ]] vim.keymap.set('n', 'Ss', 'SessionSave', { desc = 'Save session' }) vim.keymap.set('n', 'Sl', 'SessionLoad', { desc = 'Load session' }) vim.keymap.set('n', '', 'w', { desc = 'Save file' }) -- Clear highlights on search when pressing in normal mode vim.keymap.set('n', '', 'nohlsearch', { desc = 'Clear search highlights' }) vim.keymap.set('n', '', 'nohlsearch', { desc = 'Clear search highlights' }) -- Diagnostic keymaps -- vim.keymap.set('n', 'dq', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) -- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier -- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping -- or just use to exit terminal mode vim.keymap.set('t', '', '', { desc = 'Exit terminal mode' }) -- Keybinds to make split navigation easier. -- Use CTRL+ to switch between windows -- -- See `:help wincmd` for a list of all window commands vim.keymap.set('n', '', '', { desc = 'Move focus to the left window' }) vim.keymap.set('n', '', '', { desc = 'Move focus to the right window' }) vim.keymap.set('n', '', '', { desc = 'Move focus to the lower window' }) vim.keymap.set('n', '', '', { desc = 'Move focus to the upper window' }) -- Splitting & Resizing vim.keymap.set('n', 'w|', 'vsplit', { desc = 'Split window vertically' }) vim.keymap.set('n', 'w-', 'split', { desc = 'Split window horizontally' }) vim.keymap.set('n', '', 'resize +2', { desc = 'Increase window height' }) vim.keymap.set('n', '', 'resize -2', { desc = 'Decrease window height' }) vim.keymap.set('n', '', 'vertical resize +2', { desc = 'Increase window width' }) vim.keymap.set('n', '', 'vertical resize -2', { desc = 'Decrease window width' }) -- Ctrl-Shift-letter doesnt work with my setup -> Fixed by using xxd and using litteral input str vim.keymap.set('n', '^[[1;9h', 'H', { desc = 'Move window to the left' }) vim.keymap.set('n', '^[[1;9l', 'L', { desc = 'Move window to the right' }) vim.keymap.set('n', '^[[1;9j', 'J', { desc = 'Move window to the lower' }) vim.keymap.set('n', '^[[1;9k', 'K', { desc = 'Move window to the upper' }) vim.diagnostic.config { update_in_insert = false, severity_sort = true, float = { border = 'rounded', source = 'if_many' }, underline = { severity = { min = vim.diagnostic.severity.WARN } }, -- Can switch between these as you prefer virtual_text = true, -- Text shows up at the end of the line virtual_lines = false, -- Text shows up underneath the line, with virtual lines -- Auto open the float, so you can easily read the errors when jumping with `[d` and `]d` jump = { on_jump = function(_, bufnr) vim.diagnostic.open_float { bufnr = bufnr, scope = 'cursor', focus = false, } end, }, } vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) -- Center screen when jumping vim.keymap.set('n', 'n', 'nzzzv', { desc = 'Next search result (centered)' }) vim.keymap.set('n', 'N', 'Nzzzv', { desc = 'Previous search result (centered)' }) vim.keymap.set('n', '', 'zz', { desc = 'Half page down (centered)' }) vim.keymap.set('n', '', 'zz', { desc = 'Half page up (centered)' }) -- Delete without yanking vim.keymap.set({ 'n', 'v' }, 'D', '"_d', { desc = 'Delete without yanking' }) -- Paste without yanking vim.keymap.set('x', 'p', [["_dP]], { desc = 'Paste without yanking' }) -- Buffer navigation vim.keymap.set('n', 'bn', 'bnext', { desc = 'Next buffer' }) vim.keymap.set('n', 'bp', 'bprevious', { desc = 'Previous buffer' }) -- Move lines up/down vim.keymap.set('n', '', 'm .+1==', { desc = 'Move line down' }) vim.keymap.set('n', '', 'm .-2==', { desc = 'Move line up' }) vim.keymap.set('v', '', "m '>+1gv=gv", { desc = 'Move selection down' }) vim.keymap.set('v', '', "m '<-2gv=gv", { desc = 'Move selection up' }) -- Better indenting in visual mode vim.keymap.set('v', '<', '', '>gv', { desc = 'Indent right and reselect' }) -- Better J behavior vim.keymap.set('n', 'J', 'mzJ`z', { desc = 'Join lines and keep cursor position' }) -- ============================================================================ -- USEFUL FUNCTIONS -- ============================================================================ -- Copy Full File-Path vim.keymap.set('n', 'yp', function() local path = vim.fn.expand '%:p' vim.fn.setreg('+', path) print('file:', path) end) -- Copy all content of the current buffer vim.keymap.set('n', 'ya', function() vim.fn.setreg('+', vim.api.nvim_buf_get_lines(0, 0, -1, false)) vim.notify 'Copied all content of the current buffer' end) -- Delete all content of the current buffer vim.keymap.set('n', 'da', function() vim.api.nvim_buf_set_lines(0, 0, -1, false, {}) end) -- Select all content of the current buffer vim.keymap.set('n', 'sa', function() vim.api.nvim_feedkeys('ggVG', 'n', false) end) -- Basic autocommands local augroup = vim.api.nvim_create_augroup('UserConfig', {}) -- Highlight yanked text vim.api.nvim_create_autocmd('TextYankPost', { desc = 'Highlight when yanking (copying) text', group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }), callback = function() vim.hl.on_yank() end, }) -- Return to last edit position when opening files vim.api.nvim_create_autocmd('BufReadPost', { group = augroup, callback = function() local mark = vim.api.nvim_buf_get_mark(0, '"') local lcount = vim.api.nvim_buf_line_count(0) if mark[1] > 0 and mark[1] <= lcount then pcall(vim.api.nvim_win_set_cursor, 0, mark) end end, }) -- Set filetype-specific settings vim.api.nvim_create_autocmd('FileType', { group = augroup, pattern = { 'lua', 'python' }, callback = function() vim.opt_local.tabstop = 4 vim.opt_local.shiftwidth = 4 end, }) vim.api.nvim_create_autocmd('FileType', { group = augroup, pattern = { 'javascript', 'typescript', 'javascriptreact', 'typescriptreact', 'json', 'html', 'css', 'go' }, callback = function() vim.opt_local.tabstop = 2 vim.opt_local.shiftwidth = 2 end, }) -- Auto-close terminal when process exits vim.api.nvim_create_autocmd('TermClose', { group = augroup, callback = function() if vim.v.event.status == 0 then vim.api.nvim_buf_delete(0, {}) end end, }) -- Disable line numbers in terminal vim.api.nvim_create_autocmd('TermOpen', { group = augroup, callback = function() vim.opt_local.number = false vim.opt_local.relativenumber = false vim.opt_local.signcolumn = 'no' end, }) -- Auto-resize splits when window is resized vim.api.nvim_create_autocmd('VimResized', { group = augroup, callback = function() vim.cmd 'tabdo wincmd =' end, }) -- Create directories when saving files vim.api.nvim_create_autocmd('BufWritePre', { callback = function() local filepath = vim.fn.expand ':p:h' if filepath:match '^oil://' or vim.uv.fs_realpath(filepath) == nil then return end if vim.fn.isdirectory(filepath) == 0 then vim.fn.mkdir(filepath, 'p') end end, }) -- Command-line completion vim.opt.wildmenu = true vim.opt.wildmode = 'longest:full,full' vim.opt.wildignore:append { '*.o', '*.obj', '*.pyc', '*.class', '*.jar' } -- Better diff options vim.opt.diffopt:append 'linematch:60' -- Performance improvements vim.opt.redrawtime = 10000 vim.opt.maxmempattern = 20000 -- Create undo directory if it doesn't exist local undodir = vim.fn.expand '~/.vim/undodir' if vim.fn.isdirectory(undodir) == 0 then vim.fn.mkdir(undodir, 'p') end -- ============================================================================ -- FLOATING TERMINAL -- ============================================================================ -- terminal local terminal_state = { buf = nil, win = nil, is_open = false, } local function FloatingTerminal() -- If terminal is already open, close it (toggle behavior) if terminal_state.is_open and vim.api.nvim_win_is_valid(terminal_state.win) then vim.api.nvim_win_close(terminal_state.win, false) terminal_state.is_open = false return end -- Create buffer if it doesn't exist or is invalid if not terminal_state.buf or not vim.api.nvim_buf_is_valid(terminal_state.buf) then terminal_state.buf = vim.api.nvim_create_buf(false, true) -- Set buffer options for better terminal experience vim.api.nvim_buf_set_option(terminal_state.buf, 'bufhidden', 'hide') end -- Calculate window dimensions local width = math.floor(vim.o.columns * 0.8) local height = math.floor(vim.o.lines * 0.8) local row = math.floor((vim.o.lines - height) / 2) local col = math.floor((vim.o.columns - width) / 2) -- Create the floating window terminal_state.win = vim.api.nvim_open_win(terminal_state.buf, true, { relative = 'editor', width = width, height = height, row = row, col = col, style = 'minimal', border = 'rounded', }) -- Set transparency for the floating window vim.api.nvim_win_set_option(terminal_state.win, 'winblend', 0) -- Set transparent background for the window vim.api.nvim_win_set_option(terminal_state.win, 'winhighlight', 'Normal:FloatingTermNormal,FloatBorder:FloatingTermBorder') -- Define highlight groups for transparency vim.api.nvim_set_hl(0, 'FloatingTermNormal', { bg = 'none' }) vim.api.nvim_set_hl(0, 'FloatingTermBorder', { bg = 'none' }) -- Start terminal if not already running local has_terminal = false local lines = vim.api.nvim_buf_get_lines(terminal_state.buf, 0, -1, false) for _, line in ipairs(lines) do if line ~= '' then has_terminal = true break end end if not has_terminal then vim.fn.termopen(os.getenv 'SHELL') end terminal_state.is_open = true vim.cmd 'startinsert' -- Set up auto-close on buffer leave vim.api.nvim_create_autocmd('BufLeave', { buffer = terminal_state.buf, callback = function() if terminal_state.is_open and vim.api.nvim_win_is_valid(terminal_state.win) then vim.api.nvim_win_close(terminal_state.win, false) terminal_state.is_open = false end end, once = true, }) end -- Function to explicitly close the terminal local function CloseFloatingTerminal() if terminal_state.is_open and vim.api.nvim_win_is_valid(terminal_state.win) then vim.api.nvim_win_close(terminal_state.win, false) terminal_state.is_open = false end end -- Key mappings vim.keymap.set('n', 'tft', FloatingTerminal, { noremap = true, silent = true, desc = 'Toggle floating terminal' }) vim.keymap.set('n', 'tt', 'horizontal terminal', { noremap = true, silent = true, desc = 'Toggle terminal' }) vim.keymap.set('t', '', function() if terminal_state.is_open then vim.api.nvim_win_close(terminal_state.win, false) terminal_state.is_open = false end end, { noremap = true, silent = true, desc = 'Close floating terminal from terminal mode' }) -- ============================================================================ -- TABS -- ============================================================================ -- Tab display settings vim.opt.showtabline = 1 -- Always show tabline (0=never, 1=when multiple tabs, 2=always) vim.opt.tabline = '' -- Use default tabline (empty string uses built-in) -- Transparent tabline appearance vim.cmd [[ hi TabLineFill guibg=NONE ctermfg=242 ctermbg=NONE ]] -- Alternative navigation (more intuitive) vim.keymap.set('n', 'tn', 'tabnew', { desc = 'New tab' }) vim.keymap.set('n', 'tx', 'tabclose', { desc = 'Close tab' }) -- Tab moving vim.keymap.set('n', 'tm', 'tabmove', { desc = 'Move tab' }) vim.keymap.set('n', 't>', 'tabmove +1', { desc = 'Move tab right' }) vim.keymap.set('n', 't<', 'tabmove -1', { desc = 'Move tab left' }) -- Function to open file in new tab local function open_file_in_tab() vim.ui.input({ prompt = 'File to open in new tab: ', completion = 'file' }, function(input) if input and input ~= '' then vim.cmd('tabnew ' .. input) end end) end -- Function to duplicate current tab local function duplicate_tab() local current_file = vim.fn.expand '%:p' if current_file ~= '' then vim.cmd('tabnew ' .. current_file) else vim.cmd 'tabnew' end end -- Function to close tabs to the right local function close_tabs_right() local current_tab = vim.fn.tabpagenr() local last_tab = vim.fn.tabpagenr '$' for i = last_tab, current_tab + 1, -1 do vim.cmd(i .. 'tabclose') end end -- Function to close tabs to the left local function close_tabs_left() local current_tab = vim.fn.tabpagenr() for i = current_tab - 1, 1, -1 do vim.cmd '1tabclose' end end -- Enhanced keybindings vim.keymap.set('n', 'tO', open_file_in_tab, { desc = 'Open file in new tab' }) vim.keymap.set('n', 'td', duplicate_tab, { desc = 'Duplicate current tab' }) vim.keymap.set('n', 'tr', close_tabs_right, { desc = 'Close tabs to the right' }) vim.keymap.set('n', 'tL', close_tabs_left, { desc = 'Close tabs to the left' }) vim.keymap.set('n', 'x', 'q', { desc = 'Smart close buffer/tab' }) -- ============================================================ -- SECTION 3: PLUGIN MANAGER INTRO -- vim.pack intro, build hooks -- ============================================================ do local function run_build(name, cmd, cwd) local result = vim.system(cmd, { cwd = cwd }):wait() if result.code ~= 0 then local stderr = result.stderr or '' local stdout = result.stdout or '' local output = stderr ~= '' and stderr or stdout if output == '' then output = 'No output from build command.' end vim.notify(('Build failed for %s:\n%s'):format(name, output), vim.log.levels.ERROR) end end -- This autocommand runs after a plugin is installed or updated and -- runs the appropriate build command for that plugin if necessary. -- -- See `:help vim.pack-events` vim.api.nvim_create_autocmd('PackChanged', { callback = function(ev) local name = ev.data.spec.name local kind = ev.data.kind if kind ~= 'install' and kind ~= 'update' then return end if name == 'telescope-fzf-native.nvim' and vim.fn.executable 'make' == 1 then run_build(name, { 'make' }, ev.data.path) return end if name == 'LuaSnip' then if vim.fn.has 'win32' ~= 1 and vim.fn.executable 'make' == 1 then run_build(name, { 'make', 'install_jsregexp' }, ev.data.path) end return end if name == 'nvim-treesitter' then if not ev.data.active then vim.cmd.packadd 'nvim-treesitter' end vim.cmd 'TSUpdate' return end end, }) end -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. require 'kickstart.plugins' require 'custom.plugins' require 'custom.after.transparency' -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et