diff options
Diffstat (limited to '.config/nvim/lua/user')
| -rw-r--r-- | .config/nvim/lua/user/func.lua | 138 | ||||
| -rw-r--r-- | .config/nvim/lua/user/keys.lua | 434 | ||||
| -rw-r--r-- | .config/nvim/lua/user/mods.lua | 816 | ||||
| -rw-r--r-- | .config/nvim/lua/user/opts.lua | 303 | ||||
| -rw-r--r-- | .config/nvim/lua/user/pack.lua | 375 |
5 files changed, 2066 insertions, 0 deletions
diff --git a/.config/nvim/lua/user/func.lua b/.config/nvim/lua/user/func.lua new file mode 100644 index 0000000..c36d9e2 --- /dev/null +++ b/.config/nvim/lua/user/func.lua @@ -0,0 +1,138 @@ +--vim.cmd([[ +-- function RandomColorScheme() +-- let mycolors = split(globpath(&rtp,"**/colors/*.vim"),"\n") +-- exe 'so ' . mycolors[localtime() % len(mycolors)] +-- unlet mycolors +-- endfunction +-- +-- call RandomColorScheme() +-- +-- :command NewColor call RandomColorScheme() +--]]) + +--vim.cmd([[ +-- function RandomColorSchemeMyPicks() +-- let mypicks = ["pyte", "fokus", "github", "peachpuff", "morning", "simple256", "xcode", "gruvbox"] +-- let mypick = mypicks[localtime() % len(mypicks)] +-- echom mypick +-- execute 'colo' mypick +-- endfunction +-- +-- command NewColor call RandomColorSchemeMyPicks() +-- +-- let s:use_gui = exists('g:neovide') || has('gui_running') || (has('termguicolors') && &termguicolors) +-- if (s:use_gui) +-- call RandomColorSchemeMyPicks() +-- endif +--]]) + +--vim.cmd([[ +-- let g:fzf_history_dir = '~/.local/share/fzf-history' +-- map <leader>z :FZF<CR> +-- map <leader>a :Files<CR> +-- map <leader>l :Lines<CR> +-- map <leader>L :BLines<CR> +-- map <leader>B :Buffers<CR> +-- map <leader>h :History:<CR> +-- nnoremap <leader>g :Rg<CR> +-- "nnoremap <leader>t :Tags<CR> +-- nnoremap <leader>m :Marks<CR> +-- " This is the default extra key bindings +-- let g:fzf_action = { +-- \ 'ctrl-t': 'tab split', +-- \ 'ctrl-x': 'split', +-- \ 'ctrl-y': 'vsplit' } +-- let g:fzf_tags_command = 'ctags -R' +-- " Border color +-- let g:fzf_layout = {'up':'~90%', 'window': { 'width': 0.8, 'height': 0.8,'yoffset':0.5,'xoffset': 0.5, 'highlight': 'Todo', 'border': 'sharp' } } +-- let $FZF_DEFAULT_OPTS = '--layout=reverse --info=inline' +-- let $FZF_DEFAULT_COMMAND="rg --files --hidden" +-- " Customize fzf colors to match your color scheme +-- let g:fzf_colors = +-- \ { 'fg': ['fg', 'Normal'], +-- \ 'bg': ['bg', 'Normal'], +-- \ 'hl': ['fg', 'Comment'], +-- \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'], +-- \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], +-- \ 'hl+': ['fg', 'Statement'], +-- \ 'info': ['fg', 'PreProc'], +-- \ 'border': ['fg', 'Ignore'], +-- \ 'prompt': ['fg', 'Conditional'], +-- \ 'pointer': ['fg', 'Exception'], +-- \ 'marker': ['fg', 'Keyword'], +-- \ 'spinner': ['fg', 'Label'], +-- \ 'header': ['fg', 'Comment'] } +-- " Get Files +-- command! -bang -nargs=? -complete=dir Files +-- \ call fzf#vim#files(<q-args>, fzf#vim#with_preview({'options': ['--layout=reverse', '--info=inline']}), <bang>0) +-- " Get text in files with Rg +-- command! -bang -nargs=* Rg +-- \ call fzf#vim#grep( +-- \ 'rg --column --line-number --no-heading --color=always --smart-case '.shellescape(<q-args>), 1, +-- \ fzf#vim#with_preview(), <bang>0) +-- " Ripgrep advanced +-- function! RipgrepFzf(query, fullscreen) +-- let command_fmt = 'rg --column --line-number --no-heading --color=always --smart-case %s || true' +-- let initial_command = printf(command_fmt, shellescape(a:query)) +-- let reload_command = printf(command_fmt, '{q}') +-- let spec = {'options': ['--phony', '--query', a:query, '--bind', 'change:reload:'.reload_command]} +-- call fzf#vim#grep(initial_command, 1, fzf#vim#with_preview(spec), a:fullscreen) +-- endfunction +-- command! -nargs=* -bang RG call RipgrepFzf(<q-args>, <bang>0) +-- " Git grep +-- command! -bang -nargs=* GGrep +-- \ call fzf#vim#grep( +-- \ 'git grep --line-number '.shellescape(<q-args>), 0, +-- \ fzf#vim#with_preview({'dir': systemlist('git rev-parse --show-toplevel')[0]}), <bang>0) +-- command! -bang FM call fzf#run(fzf#wrap({'source': 'cat ~/.fzf-marks | sed "s/.*: \(.*\)$/\1/" | sed "s#~#${HOME}#"', 'sink': 'lcd'}, <bang>0)) +--]]) +-- +--vim.cmd([[ +-- " Enable mouse scrollback +-- set mouse=a +-- tnoremap <Esc> <C-\><C-n> +-- tnoremap <c-b> <c-\><c-n> +-- function! ClearTerminal() +-- set scrollback=1 +-- let &g:scrollback=1 +-- echo &scrollback +-- call feedkeys("\i") +-- call feedkeys("clear\<CR>") +-- call feedkeys("\<C-\>\<C-n>") +-- call feedkeys("\i") +-- sleep 100m +-- let &scrollback=s:scroll_value +-- endfunction +--]]) +-- +--vim.cmd([[ +-- " :Rename {newname} +-- function! RenameFile() +-- let old_name = expand('%') +-- let new_name = input('New file name: ', expand('%'), 'file') +-- if new_name != '' && new_name != old_name +-- exec ':saveas ' . new_name +-- exec ':silent !rm ' . old_name +-- redraw! +-- endif +-- endfunction +-- map <leader>re :call RenameFile()<cr> +--]]) + +--vim.cmd([[ +-- " Markdown Settings +-- autocmd BufNewFile,BufReadPost *.md set filetype=markdown +-- let g:markdown_fenced_languages = ['html', 'python', 'bash=sh', 'sql', 'pug'] +-- let g:markdown_minlines = 100 +-- let g:instant_markdown_autostart = 0 +--]]) +-- +--vim.cmd([[ +-- " On The Fly Table mode +-- function! s:isAtStartOfLine(mapping) +-- let text_before_cursor = getline('.')[0 : col('.')-1] +-- let mapping_pattern = '\V' . escape(a:mapping, '\') +-- let comment_pattern = '\V' . escape(substitute(&l:commentstring, '%s.*$', '', ''), '\') +-- return (text_before_cursor =~? '^' . ('\v(' . comment_pattern . '\v)?') . '\s*\v' . mapping_pattern . '\v$') +-- endfunction +--]]) diff --git a/.config/nvim/lua/user/keys.lua b/.config/nvim/lua/user/keys.lua new file mode 100644 index 0000000..ebafd21 --- /dev/null +++ b/.config/nvim/lua/user/keys.lua @@ -0,0 +1,434 @@ +local keymap = vim.keymap +local map = function(mode, l, r, opts) + opts = opts or {} + opts.silent = true + opts.noremap = true + keymap.set(mode, l, r, opts) +end +local term_opts = { noremap = true, silent = false } +local bufnr = vim.api.nvim_get_current_buf() + +-- Semi-colon as leader key +vim.g.mapleader = ';' + +-- "jk" and "kj" to exit insert-mode +map('i', 'jk', '<esc>') + +-- Jump to next match on line using `.` instead of `;` NOTE: commented out in favour of "ggandor/flit.nvim" +--map("n", ".", ";") + +-- Repeat last command using `<Space>` instead of `.` NOTE: commented out in favour of "ggandor/flit.nvim" +--map("n", "<Space>", ".") + +-- Reload nvim config +map('n', '<leader><CR>', "<cmd>luafile ~/.config/nvim/init.lua<CR> | :echom ('Nvim config loading...') | :sl! | echo ('')<CR>") + +--------------- Extended Operations --------------- +-- Conditional 'q' to quit on floating/quickfix/help windows otherwise still use it for macros +-- TODO: Have a list of if available on system/packages, example "Zen Mode" to not work on it (quit Zen Mode) +map('n', 'q', function() + local config = vim.api.nvim_win_get_config(0) + if config.relative ~= '' then -- is_floating_window? + return ':silent! close!<CR>' + elseif vim.o.buftype == 'quickfix' then + return ':quit<CR>' + elseif vim.o.buftype == 'help' then + return ':close<CR>' + else + return 'q' + end +end, { expr = true, replace_keycodes = true }) + +-- Combine buffers list with buffer name +map('n', '<Leader>b', ':buffers<CR>:buffer<Space>') + +-- Buffer confirmation +map('n', '<leader>y', ':BufferPick<CR>') + +-- Map buffer next, prev and delete to <leader>+(n/p/d) respectively +map('n', '<leader>n', ':bn<cr>') +map('n', '<leader>p', ':bp<cr>') +map('n', '<leader>d', ':bd<cr>') + +-- Delete file of current buffer +map('n', '<leader>rm', "<CMD>call delete(expand('%')) | bdelete!<CR>") + +-- List marks +map('n', '<Leader>m', ':marks<CR>') + +-- Messages +map('n', '<Leader>M', ':messages<CR>') + +-- Clear messages or just refresh/redraw the screen +map('n', '<leader>u', ":echo '' | redraw<CR>") + +-- Unsets the 'last search pattern' register by hitting return +--map("n", "<CR>", "!silent :noh<CR><CR>") + +-- Toggle set number +map('n', '<leader>$', ':NumbersToggle<CR>') +map('n', '<leader>%', ':NumbersOnOff<CR>') + +-- Easier split navigations, just ctrl-j instead of ctrl-w then j +map('t', '<C-[>', '<C-\\><C-N>') +map('t', '<C-h>', '<C-\\><C-N><C-h>') +map('t', '<C-j>', '<C-\\><C-N><C-j>') +map('t', '<C-k>', '<C-\\><C-N><C-k>') +map('t', '<C-l>', '<C-\\><C-N><C-l>') + +-- Split window +map('n', '<leader>h', ':split<CR>') +map('n', '<leader>v', ':vsplit<CR>') +map('n', '<leader>c', '<C-w>c') + +-- Resize Panes +map('n', '<Leader>+', ':resize +5<CR>') +map('n', '<Leader>-', ':resize -5<CR>') +map('n', '<Leader><', ':vertical resize +5<CR>') +map('n', '<Leader>>', ':vertical resize -5<CR>') +map('n', '<Leader>=', '<C-w>=') + +-- Map Alt+(h/j/k/l) in insert(include terminal/command) mode to move directional +map({ 'i', 't', 'c' }, '<A-h>', '<left>') +map({ 'i', 't', 'c' }, '<A-j>', '<down>') +map({ 'i', 't', 'c' }, '<A-k>', '<up>') +map({ 'i', 't', 'c' }, '<A-l>', '<right>') + +-- Create tab, edit and move between them +map('n', '<C-T>n', ':tabnew<CR>') +map('n', '<C-T>e', ':tabedit') +map('n', '<leader>[', ':tabprev<CR>') +map('n', '<leader>]', ':tabnext<CR>') + +-- "Zoom" a split window into a tab and/or close it +--map("n", "<Leader>,", ":tabnew %<CR>") +--map("n", "<Leader>.", ":tabclose<CR>") + +-- Vim TABs +map('n', '<leader>1', '1gt<CR>') +map('n', '<leader>2', '2gt<CR>') +map('n', '<leader>3', '3gt<CR>') +map('n', '<leader>4', '4gt<CR>') +map('n', '<leader>5', '5gt<CR>') +map('n', '<leader>6', '6gt<CR>') +map('n', '<leader>7', '7gt<CR>') +map('n', '<leader>8', '8gt<CR>') +map('n', '<leader>9', '9gt<CR>') +map('n', '<leader>0', '10gt<CR>') + +-- Hitting ESC when inside a terminal to get into normal mode +--map("t", "<Esc>", [[<C-\><C-N>]]) + +-- Move block (indentation) easily +map('n', '<', '<<', term_opts) +map('n', '>', '>>', term_opts) +map('x', '<', '<gv', term_opts) +map('x', '>', '>gv', term_opts) + +-- Set alt+(j/k) to switch lines of texts or simply move them +map('n', '<A-k>', ':let save_a=@a<Cr><Up>"add"ap<Up>:let @a=save_a<Cr>') +map('n', '<A-j>', ':let save_a=@a<Cr>"add"ap:let @a=save_a<Cr>') + +-- Toggle Diff +map('n', '<leader>df', '<Cmd>call utils#ToggleDiff()<CR>') + +-- Toggle Verbose +map('n', '<leader>vt', '<Cmd>call utils#VerboseToggle()<CR>') + +-- Jump List +map('n', '<leader>j', '<Cmd>call utils#GotoJump()<CR>') + +-- Map delete to Ctrl+l +map('i', '<C-l>', '<Del>') + +-- Clear screen +map('n', '<leader><C-l>', '<Cmd>!clear<CR>') + +-- Change file to an executable +map('n', '<Leader>x', ":lua require('user.mods').Toggle_executable()<CR> | :echom ('Toggle executable')<CR> | :sl! | echo ('')<CR>") +-- map("n", "<leader>x", ":!chmod +x %<CR>") + +-- Paste without replace clipboard +map('v', 'p', '"_dP') + +-- Swap two pieces of text, use x to cut in visual mode, then use Ctrl-x in +-- visual mode to select text to swap with +--map("v", "<C-X>", "<Esc>`.``gvP``P") + +-- Change Working Directory to current project +map('n', '<leader>cd', ':cd %:p:h<CR>:pwd<CR>') + +-- Open the current file in the default program (on Mac this should just be just `open`) +map('n', '<leader>o', ':!xdg-open %<cr><cr>') + +-- URL handling +if vim.fn.has('mac') == 1 then + map('', 'gx', '<Cmd>call jobstart(["open", expand("<cfile>")], {"detach": v:true})<CR>', {}) +elseif vim.fn.has('unix') == 1 then + map('', 'gx', '<Cmd>call jobstart(["xdg-open", expand("<cfile>")], {"detach": v:true})<CR>', {}) +elseif vim.fn.has('wsl') == 1 then + map('', 'gx', '<Cmd>call jobstart(["wslview", expand("<cfile>")], {"detach": v:true})<CR>', {}) +else + map[''].gx = { '<Cmd>lua print("Error: gx is not supported on this OS!")<CR>' } +end + +-- Search and replace +map('v', '<leader>sr', 'y:%s/<C-r><C-r>"//g<Left><Left>c') + +-- Substitute globally and locally in the selected region. +map('n', '<leader>s', ':%s//g<Left><Left>') +map('v', '<leader>s', ':s//g<Left><Left>') + +-- Toggle completion +map('n', '<Leader>tc', ':lua require("user.mods").toggle_completion()<CR>') + +-- Disable default completion. +map('i', '<C-n>', '<Nop>') +map('i', '<C-p>', '<Nop>') + +-- Set line wrap +map('n', '<M-z>', function() + local wrap_status = vim.api.nvim_exec('set wrap ?', true) + + if wrap_status == 'nowrap' then + vim.api.nvim_command('set wrap linebreak') + print('Wrap enabled') + else + vim.api.nvim_command('set wrap nowrap') + print('Wrap disabled') + end +end, { silent = true }) + +-- Toggle between folds +--utils.map("n", "<F2>", "&foldlevel ? 'zM' : 'zR'", { expr = true }) + +-- Use space to toggle fold +map('n', '<Space>', 'za') + +-- Make a copy of current file +--vim.cmd([[ +-- map <leader>s :up \| saveas! %:p:r-<C-R>=strftime("%y.%m.%d-%H:%M")<CR>-bak.<C-R>=expand("%:e")<CR> \| 3sleep \| e #<CR> +--]]) +map('n', '<leader>.b', ':!cp % %.backup<CR>') + +-- Toggle transparency +map('n', '<leader>tb', ':call utils#Toggle_transparent_background()<CR>') + +-- Toggle zoom +map('n', '<leader>z', ':call utils#ZoomToggle()<CR>') +map('n', '<C-w>z', '<C-w>|<C-w>_') + +-- Toggle statusline +map('n', '<S-h>', ':call utils#ToggleHiddenAll()<CR>') + +-- Open last closed buffer +map('n', '<C-t>', ':call OpenLastClosed()<CR>') + +---------------- Plugin Operations ---------------- +-- Packer +map('n', '<leader>Pc', '<cmd>PackerCompile<cr>') +map('n', '<leader>Pi', '<cmd>PackerInstall<cr>') +map('n', '<leader>Ps', '<cmd>PackerSync<cr>') +map('n', '<leader>PS', '<cmd>PackerStatus<cr>') +map('n', '<leader>Pu', '<cmd>PackerUpdate<cr>') + +-- Tmux navigation (aserowy/tmux.nvim) +map('n', '<C-h>', '<CMD>NavigatorLeft<CR>') +map('n', '<C-l>', '<CMD>NavigatorRight<CR>') +map('n', '<C-k>', '<CMD>NavigatorUp<CR>') +map('n', '<C-j>', '<CMD>NavigatorDown<CR>') + +-- ToggleTerm +map({ 'n', 't' }, '<leader>tt', '<cmd>ToggleTerm<CR>') +map({ 'n', 't' }, '<leader>th', '<cmd>lua Horizontal_term_toggle()<CR>') +map({ 'n', 't' }, '<leader>tv', '<cmd>lua Vertical_term_toggle()<CR>') + +-- LazyGit +map({ 'n', 't' }, '<leader>gg', '<cmd>lua Lazygit_toggle()<CR>') + +map('n', '<leader>tg', '<cmd>lua Gh_dash()<CR>') + +-- Fugitive git bindings +map('n', '<leader>gs', vim.cmd.Git) +map('n', '<leader>ga', ':Git add %:p<CR><CR>') +--map("n", "<leader>gs", ":Gstatus<CR>") +map('n', '<leader>gc', ':Gcommit -v -q<CR>') +map('n', '<leader>gt', ':Gcommit -v -q %:p<CR>') +--map("n", "<leader>gd", ":Gdiff<CR>") +map('n', '<leader>ge', ':Gedit<CR>') +--map("n", "<leader>gr", ":Gread<Cj>") +map('n', '<leader>gw', ':Gwrite<CR><CR>') +map('n', '<leader>gl', ':silent! Glog<CR>:bot copen<CR>') +--map("n", "<leader>gp", ":Ggrep<Space>") +--map("n", "<Leader>gp", ":Git push<CR>") +--map("n", "<Leader>gb", ":Gblame<CR>") +map('n', '<leader>gm', ':Gmove<Space>') +--map("n", "<leader>gb", ":Git branch<Space>") +--map("n", "<leader>go", ":Git checkout<Space>") +--map("n", "<leader>gps", ":Dispatch! git push<CR>") +--map("n", "<leader>gpl", ":Dispatch! git pull<CR>") + +-- Telescope +map('n', '<leader>ff', ":cd %:p:h<CR>:pwd<CR><cmd>lua require('telescope.builtin').find_files()<cr>") -- find files with hidden option +map('n', '<leader>fF', ":cd %:p:h<CR>:pwd<CR><cmd>lua require('user.mods').findFilesInCwd()<CR>", { noremap = true, silent = true, desc = 'Find files in cwd' }) +map('n', '<leader>f.', function() + require('telescope.builtin').find_files({ hidden = false, no_ignore = true }) +end) -- find all files +map('n', '<leader>fg', "<cmd>lua require('telescope.builtin').live_grep()<cr>") +map('n', '<leader>fb', "<cmd>lua require('telescope.builtin').buffers()<cr>") +map('n', '<leader>fh', "<cmd>lua require('telescope.builtin').help_tags()<cr>") +map('n', '<leader>fc', "<cmd>lua require('telescope.builtin').commands()<cr>") +map('n', '<leader>cf', '<cmd>Telescope changed_files<cr>') +map('n', '<leader>fp', '<cmd>Telescope pickers<cr>') +map('n', '<leader>fd', "<cmd>lua require('telescope.builtin').diagnostics()<cr>") +map('n', '<leader>fk', "<cmd>lua require('telescope.builtin').keymaps()<cr>") +map('n', '<leader>fr', "<cmd>lua require('telescope.builtin').registers({})<CR>") -- registers picker +map('n', '<leader>fm', "<cmd>lua require('telescope').extensions.media_files.media_files({})<cr>") -- find media files +map('n', '<leader>fi', "<cmd>lua require('telescope').extensions.notify.notify({})<cr>") -- find notifications +map('n', '<Leader>fs', '<cmd>lua require("session-lens").search_session()<CR>') +map('n', '<leader>ffd', [[<Cmd>lua require'plugins.telescope'.find_dirs()<CR>]]) -- find dies +map('n', '<leader>ff.', [[<Cmd>lua require'plugins.telescope'.find_configs()<CR>]]) -- find configs +map('n', '<leader>ffs', [[<Cmd>lua require'plugins.telescope'.find_scripts()<CR>]]) -- find scripts +map('n', '<leader>ffw', [[<Cmd>lua require'plugins.telescope'.find_projects()<CR>]]) -- find projects +map('n', '<leader>ffb', [[<Cmd>lua require'plugins.telescope'.find_books()<CR>]]) -- find books +map('n', '<leader>ffn', [[<Cmd>lua require'plugins.telescope'.find_notes()<CR>]]) -- find notes +map('n', '<leader>fgn', [[<Cmd>lua require'plugins.telescope'.grep_notes()<CR>]]) -- search notes +map('n', '<Leader>ffr', "<cmd>lua require('telescope').extensions.recent_files.pick()<CR>") +map('n', '<leader>ffc', "<cmd>lua require('telescope.builtin').current_buffer_fuzzy_find()<cr>") +map('n', '<Leader>f/', "<cmd>lua require('telescope').extensions.file_browser.file_browser()<CR>") +--map("n", "<leader>f/", "<cmd>lua require('plugins.telescope').curbuf()<cr>") -- find files with hidden option +-- Map a shortcut to open the picker. + +-- FZF +map('n', '<leader>fz', "<cmd>lua require('fzf-lua').files()<CR>") + +-- Nvim-tree +map('n', '<leader>f', '<cmd>Rooter<CR>:NvimTreeToggle<CR>', {}) +map('n', '<leader>F', ':NvimTreeFindFileToggle<CR>', { noremap = false, silent = true }) + +-- Undotree +map('n', '<leader>u', vim.cmd.UndotreeToggle) + +-- Markdown-preview +map('n', '<leader>md', '<Plug>MarkdownPreviewToggle') +map('n', '<leader>mg', '<CMD>Glow<CR>') + +-- Autopairs +map('n', '<leader>ww', "<cmd>lua require('user.mods').Toggle_autopairs()<CR>") + +-- Zen-mode toggle +map('n', '<leader>zm', "<CMD>ZenMode<CR> | :echom ('Zen Mode')<CR> | :sl! | echo ('')<CR>") + +-- Vim-rooter +map('n', '<leader>ro', "<CMD>Rooter<CR> | :echom ('cd to root/project directory')<CR> | :sl! | echo ('')<CR>", term_opts) + +-- Trouble (UI to show diagnostics) +map('n', '<leader>t', ':cd %:p:h<CR>:pwd<CR><CMD>TroubleToggle<CR>') +map('n', '<leader>tw', ':cd %:p:h<CR>:pwd<CR><CMD>TroubleToggle workspace_diagnostics<CR>') +map('n', '<leader>td', ':cd %:p:h<CR>:pwd<CR><CMD>TroubleToggle document_diagnostics<CR>') +map('n', '<leader>tq', ':cd %:p:h<CR>:pwd<CR><CMD>TroubleToggle quickfix<CR>') +map('n', '<leader>tl', ':cd %:p:h<CR>:pwd<CR><CMD>TroubleToggle loclist<CR>') +map('n', 'gR', '<CMD>TroubleToggle lsp_references<CR>') + +-- Null-ls +map('n', '<leader>ls', '<CMD>NullLsToggle<CR>') + +-- Replacer +map('n', '<Leader>qr', ':lua require("replacer").run()<CR>') + +-- Quickfix +map('n', '<leader>q', function() + if vim.fn.getqflist({ winid = 0 }).winid ~= 0 then + require('plugins.quickfix').close() + else + require('plugins.quickfix').open() + end +end, { desc = 'Toggle quickfix window' }) + +-- Move to the next and previous item in the quickfixlist +map('n', ']c', '<Cmd>cnext<CR>') +map('n', '[c', '<Cmd>cprevious<CR>') + +-- Location list +map('n', '<leader>l', '<cmd>lua require("plugins.loclist").loclist_toggle()<CR>') + +-- Dap (debugging) +local dap_ok, dap = pcall(require, 'dap') +local dap_ui_ok, ui = pcall(require, 'dapui') + +if not (dap_ok and dap_ui_ok) then + require('notify')('nvim-dap or dap-ui not installed!', 'warning') + return +end + +vim.fn.sign_define('DapBreakpoint', { text = '๐' }) + +-- Start debugging session +map('n', '<leader>ds', function() + dap.continue() + ui.toggle({}) + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('<C-w>=', false, true, true), 'n', false) -- Spaces buffers evenly +end) + +-- Set breakpoints, get variable values, step into/out of functions, etc. +map('n', '<leader>dC', dap.continue) +-- map("n", "<leader>dC", dap.close) +-- map("n", "<leader>dt", dap.terminate) +map('n', '<leader>dt', ui.toggle) +map('n', '<leader>dd', function() + dap.disconnect({ terminateDebuggee = true }) +end) +map('n', '<leader>dn', dap.step_over) +map('n', '<leader>di', dap.step_into) +map('n', '<leader>do', dap.step_out) +map('n', '<leader>db', dap.toggle_breakpoint) +map('n', '<leader>dB', function() + dap.clear_breakpoints() + require('notify')('Breakpoints cleared', 'warn') +end) +map('n', '<leader>dl', require('dap.ui.widgets').hover) +map('n', '<leader>de', function() + require('dapui').float_element() +end, { desc = 'Open Element' }) +map('n', '<leader>dq', function() + require('dapui').close() + require('dap').repl.close() + local session = require('dap').session() + if session then + require('dap').terminate() + end + require('nvim-dap-virtual-text').refresh() +end, { desc = 'Terminate Debug' }) +map('n', '<leader>dc', function() + require('telescope').extensions.dap.commands() +end, { desc = 'DAP-Telescope: Commands' }) +--vim.keymap.set("n", "<leader>B", ":lua require'dap'.set_breakpoint(vim.fn.input('Breakpoint condition: '))<CR>") +--vim.keymap.set("v", "<leader>B", ":lua require'dap'.set_breakpoint(vim.fn.input('Breakpoint condition: '))<CR>") +--vim.keymap.set("n", "<leader>lp", ":lua require'dap'.set_breakpoint(nil, nil, vim.fn.input('Log point message: '))<CR>") +--vim.keymap.set("n", "<leader>dr", ":lua require'dap'.repl.open()<CR>") + +-- Close debugger and clear breakpoints +--map("n", "<leader>de", function() +-- dap.clear_breakpoints() +-- ui.toggle({}) +-- dap.terminate() +-- vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<C-w>=", false, true, true), "n", false) +-- require("notify")("Debugger session ended", "warn") +--end) + +-- Toggle Dashboard +map('n', '<leader><Space>', '<CMD>lua require("user.mods").toggle_dashboard()<CR>') + +-- Lsp Lines toggle +map('', '<Leader>ll', require('lsp_lines').toggle, { desc = 'Toggle lsp_lines' }) + +-- SnipRun +map({ 'n', 'v' }, '<leader>r', '<Plug>SnipRun<CR>') + +-- Codi +map('n', '<leader>co', '<CMD>lua require("user.mods").toggleCodi()<CR>') + +-- Scratch buffer +map('n', '<leader>ss', '<CMD>lua require("user.mods").Scratch("float")<CR>') +map('n', '<leader>sh', '<CMD>lua require("user.mods").Scratch("horizontal")<CR>') +map('n', '<leader>sv', '<CMD>lua require("user.mods").Scratch("vertical")<CR>') diff --git a/.config/nvim/lua/user/mods.lua b/.config/nvim/lua/user/mods.lua new file mode 100644 index 0000000..6420ed5 --- /dev/null +++ b/.config/nvim/lua/user/mods.lua @@ -0,0 +1,816 @@ +local M = {} + +--- Shorten Function Names +local fn = vim.fn +function M.executable(name) + if fn.executable(name) > 0 then + return true + end + + return false +end + +-------------------------------------------------- + +--- Check whether a feature exists in Nvim +--- @feat: string +--- the feature name, like `nvim-0.7` or `unix`. +--- return: bool +M.has = function(feat) + if fn.has(feat) == 1 then + return true + end + + return false +end + +-------------------------------------------------- + +-- Format on save +local format_augroup = vim.api.nvim_create_augroup('LspFormatting', {}) +require('null-ls').setup({ + -- you can reuse a shared lspconfig on_attach callback here + on_attach = function(client, bufnr) + if client.supports_method('textDocument/formatting') then + vim.api.nvim_clear_autocmds({ group = format_augroup, buffer = bufnr }) + vim.api.nvim_create_autocmd('BufWritePre', { + group = format_augroup, + buffer = bufnr, + callback = function() + -- on 0.8, you should use vim.lsp.buf.format({ bufnr = bufnr }) instead + --vim.lsp.buf.formatting_seq_sync() + vim.lsp.buf.format({ bufnr = bufnr }) + end, + }) + end + end, +}) + +vim.cmd([[autocmd BufWritePre <buffer> lua vim.lsp.buf.format()]]) +--vim.cmd [[autocmd BufWritePre * lua vim.lsp.buf.format()]] + +-------------------------------------------------- + +---Determine if a value of any type is empty +---@param item any +---@return boolean? +function M.empty(item) + if not item then + return true + end + local item_type = type(item) + if item_type == 'string' then + return item == '' + end + if item_type == 'number' then + return item <= 0 + end + if item_type == 'table' then + return vim.tbl_isempty(item) + end + return item ~= nil +end + +-------------------------------------------------- + +--- Create a dir if it does not exist +function M.may_create_dir(dir) + local res = fn.isdirectory(dir) + + if res == 0 then + fn.mkdir(dir, 'p') + end +end + +-------------------------------------------------- + +--- Toggle cmp completion +vim.g.cmp_toggle_flag = false -- initialize +local normal_buftype = function() + return vim.api.nvim_buf_get_option(0, 'buftype') ~= 'prompt' +end +M.toggle_completion = function() + local ok, cmp = pcall(require, 'cmp') + if ok then + local next_cmp_toggle_flag = not vim.g.cmp_toggle_flag + if next_cmp_toggle_flag then + print('completion on') + else + print('completion off') + end + cmp.setup({ + enabled = function() + vim.g.cmp_toggle_flag = next_cmp_toggle_flag + if next_cmp_toggle_flag then + return normal_buftype + else + return next_cmp_toggle_flag + end + end, + }) + else + print('completion not available') + end +end + +-------------------------------------------------- + +--- Make sure using latest neovim version +function M.get_nvim_version() + local actual_ver = vim.version() + + local nvim_ver_str = string.format('%d.%d.%d', actual_ver.major, actual_ver.minor, actual_ver.patch) + return nvim_ver_str +end + +function M.add_pack(name) + local status, error = pcall(vim.cmd, 'packadd ' .. name) + + return status +end + +-------------------------------------------------- + +-- Define a global function to retrieve LSP clients based on Neovim version +function M.get_lsp_clients(bufnr) + local mods = require('user.mods') + --local expected_ver = '0.10.0' + local nvim_ver = mods.get_nvim_version() + + local version_major, version_minor = string.match(nvim_ver, '(%d+)%.(%d+)') + version_major = tonumber(version_major) + version_minor = tonumber(version_minor) + + if version_major > 0 or (version_major == 0 and version_minor >= 10) then + return vim.lsp.get_clients({ buffer = bufnr }) + else + return vim.lsp.buf_get_clients() + end +end + +-------------------------------------------------- + +--- Toggle autopairs on/off (requires "windwp/nvim-autopairs") +function M.Toggle_autopairs() + local ok, autopairs = pcall(require, 'nvim-autopairs') + if ok then + if autopairs.state.disabled then + autopairs.enable() + print('autopairs on') + else + autopairs.disable() + print('autopairs off') + end + else + print('autopairs not available') + end +end + +-------------------------------------------------- + +--- Make vim-rooter message disappear after making it's changes +--vim.cmd([[ +--let timer = timer_start(1000, 'LogTrigger', {}) +--func! LogTrigger(timer) +-- silent! +--endfunc +--]]) +-- +--vim.cmd([[ +--function! ConfigureChDir() +-- echo ('') +--endfunction +--" Call after vim-rooter changes the root dir +--autocmd User RooterChDir :sleep! | call LogTrigger(timer) | call ConfigureChDir() +--]]) + +function M.findFilesInCwd() + vim.cmd('let g:rooter_manual_only = 1') -- Toggle the rooter plugin + require('plugins.telescope').findhere() + vim.defer_fn(function() + vim.cmd('let g:rooter_manual_only = 0') -- Change back to automatic rooter + end, 100) +end + +--function M.findFilesInCwd() +-- vim.cmd("let g:rooter_manual_only = 1") -- Toggle the rooter plugin +-- require("plugins.telescope").findhere() +-- --vim.cmd("let g:rooter_manual_only = 0") -- Change back to automatic rooter +--end + +-------------------------------------------------- + +-- Toggle the executable permission +function M.Toggle_executable() + local current_file = vim.fn.expand('%:p') + local executable = vim.fn.executable(current_file) == 1 + + if executable then + -- File is executable, unset the executable permission + vim.fn.system('chmod -x ' .. current_file) + --print(current_file .. ' is no longer executable.') + print('No longer executable') + else + -- File is not executable, set the executable permission + vim.fn.system('chmod +x ' .. current_file) + --print(current_file .. ' is now executable.') + print('Now executable') + end +end + +-------------------------------------------------- + +-- Set bare dotfiles repository git environment variables dynamically + +-- Set git enviornment variables +--function M.Set_git_env_vars() +-- local git_dir_job = vim.fn.jobstart({ "git", "rev-parse", "--git-dir" }) +-- local command_status = vim.fn.jobwait({ git_dir_job })[1] +-- if command_status > 0 then +-- vim.env.GIT_DIR = vim.fn.expand("$HOME/.cfg") +-- vim.env.GIT_WORK_TREE = vim.fn.expand("~") +-- else +-- vim.env.GIT_DIR = nil +-- vim.env.GIT_WORK_TREE = nil +-- end +-- -- Launch terminal emulator with Git environment variables set +-- --require("toggleterm").exec(string.format([[%s %s]], os.getenv("SHELL"), "-i")) +--end + +------ + +local prev_cwd = '' + +function M.Set_git_env_vars() + local cwd = vim.fn.getcwd() + if prev_cwd == '' then + -- First buffer being opened, set prev_cwd to cwd + prev_cwd = cwd + elseif cwd ~= prev_cwd then + -- Working directory has changed since last buffer was opened + prev_cwd = cwd + local git_dir_job = vim.fn.jobstart({ 'git', 'rev-parse', '--git-dir' }) + local command_status = vim.fn.jobwait({ git_dir_job })[1] + if command_status > 0 then + vim.env.GIT_DIR = vim.fn.expand('$HOME/.cfg') + vim.env.GIT_WORK_TREE = vim.fn.expand('~') + else + vim.env.GIT_DIR = nil + vim.env.GIT_WORK_TREE = nil + end + end +end + +vim.cmd([[augroup my_git_env_vars]]) +vim.cmd([[ autocmd!]]) +vim.cmd([[ autocmd BufEnter * lua require('user.mods').Set_git_env_vars()]]) +vim.cmd([[ autocmd VimEnter * lua require('user.mods').Set_git_env_vars()]]) +vim.cmd([[augroup END]]) + +-------------------------------------------------- + +--- Update Tmux Status Vi-mode +function M.update_tmux_status() + local mode = vim.api.nvim_eval('mode()') + -- Determine the mode name based on the mode value + local mode_name + if mode == 'n' then + mode_name = '-- NORMAL --' + elseif mode == 'i' or mode == 'ic' then + mode_name = '-- INSERT --' + else + mode_name = '-- NORMAL --' --'-- COMMAND --' + end + + -- Write the mode name to the file + local file = io.open(os.getenv('HOME') .. '/.vi-mode', 'w') + file:write(mode_name) + file:close() + if nvim_running then + -- Neovim is running, update the mode file and refresh tmux + VI_MODE = '' -- Clear VI_MODE to show Neovim mode + vim.cmd('silent !tmux refresh-client -S') + end + ---- Force tmux to update the status + vim.cmd('silent !tmux refresh-client -S') +end + +vim.cmd([[ + augroup TmuxStatus + autocmd! + autocmd InsertLeave,InsertEnter * lua require("user.mods").update_tmux_status() + autocmd VimEnter * lua require("user.mods").update_tmux_status() + autocmd BufEnter * lua require("user.mods").update_tmux_status() + autocmd ModeChanged * lua require("user.mods").update_tmux_status() + autocmd WinEnter,WinLeave * lua require("user.mods").update_tmux_status() + augroup END +]]) + +-- Add autocmd for <esc> +-- Add autocmd to check when tmux switches panes/windows +--autocmd InsertLeave,InsertEnter * lua require("user.mods").update_tmux_status() +--autocmd BufEnter * lua require("user.mods").update_tmux_status() +--autocmd WinEnter,WinLeave * lua require("user.mods").update_tmux_status() + +--autocmd WinEnter,WinLeave * lua require("user.mods").update_tmux_status() +--autocmd VimResized * lua require("user.mods").update_tmux_status() +--autocmd FocusGained * lua require("user.mods").update_tmux_status() +--autocmd FocusLost * lua require("user.mods").update_tmux_status() +--autocmd CmdwinEnter,CmdwinLeave * lua require("user.mods").update_tmux_status() + +-------------------------------------------------- + +-- function OpenEmulatorList() +-- local emulatorsBuffer = vim.api.nvim_create_buf(false, true) +-- vim.api.nvim_buf_set_lines(emulatorsBuffer, 0, 0, true, {"Some text"}) +-- vim.api.nvim_open_win( +-- emulatorsBuffer, +-- false, +-- { +-- relative='win', row=3, col=3, width=12, height=3 +-- } +-- ) +-- end +-- +-- vim.api.nvim_create_user_command('OpenEmulators', OpenEmulatorList, {}) + +--local api = vim.api +--local fn = vim.fn +--local cmd = vim.cmd +-- +--local function bufremove(opts) +-- local target_buf_id = api.nvim_get_current_buf() +-- +-- -- Do nothing if buffer is in modified state. +-- if not opts.force and api.nvim_buf_get_option(target_buf_id, 'modified') then +-- return false +-- end +-- +-- -- Hide target buffer from all windows. +-- vim.tbl_map(function(win_id) +-- win_id = win_id or 0 +-- +-- local current_buf_id = api.nvim_win_get_buf(win_id) +-- +-- api.nvim_win_call(win_id, function() +-- -- Try using alternate buffer +-- local alt_buf_id = fn.bufnr('#') +-- if alt_buf_id ~= current_buf_id and fn.buflisted(alt_buf_id) == 1 then +-- api.nvim_win_set_buf(win_id, alt_buf_id) +-- return +-- end +-- +-- -- Try using previous buffer +-- cmd('bprevious') +-- if current_buf_id ~= api.nvim_win_get_buf(win_id) then +-- return +-- end +-- +-- -- Create new listed scratch buffer +-- local new_buf = api.nvim_create_buf(true, true) +-- api.nvim_win_set_buf(win_id, new_buf) +-- end) +-- +-- return true +-- end, fn.win_findbuf(target_buf_id)) +-- +-- cmd(string.format('bdelete%s %d', opts.force and '!' or '', target_buf_id)) +--end +-- +---- Assign bufremove to a global variable +--_G.bufremove = bufremove + +--vim.cmd([[ +-- augroup NvimTreeDelete +-- autocmd! +-- autocmd FileType NvimTree lua require('user.mods').enew_on_delete() +-- augroup END +--]]) +-- +--function M.enew_on_delete() +-- if vim.bo.buftype == 'nofile' then +-- vim.cmd('enew') +-- end +--end + +-- Update Neovim +--function M.Update_neovim() +-- -- Run the commands to download and extract the latest version +-- os.execute("curl -L -o nvim-linux64.tar.gz https://github.com/neovim/neovim/releases/latest/download/nvim-linux64.tar.gz") +-- os.execute("tar xzvf nvim-linux64.tar.gz") +-- -- Replace the existing Neovim installation with the new version +-- os.execute("rm -rf $HOME/.local/bin/nvim") +-- os.execute("mv nvim-linux64 $HOME/.local/bin/nvim") +-- +-- -- Clean up the downloaded file +-- os.execute("rm nvim-linux64.tar.gz") +-- +-- -- Print a message to indicate the update is complete +-- print("Neovim has been updated to the latest version.") +--end +-- +---- Bind a keymap to the update_neovim function (optional) +--vim.api.nvim_set_keymap('n', '<leader>u', '<cmd> lua require("user.mods").Update_neovim()<CR>', { noremap = true, silent = true }) + +-- Define a function to create a floating window and run the update process inside it +function M.Update_neovim() + -- Create a new floating window + local bufnr, winid = vim.api.nvim_create_buf(false, true) + vim.api.nvim_open_win(bufnr, true, { + relative = 'editor', + width = 80, + height = 20, + row = 2, + col = 2, + style = 'minimal', + border = 'single', + }) + + -- Function to append a line to the buffer in the floating window + local function append_line(line) + vim.api.nvim_buf_set_option(bufnr, 'modifiable', true) + vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, { line }) + vim.api.nvim_buf_set_option(bufnr, 'modifiable', false) + end + + -- Download the latest version of Neovim + append_line('Downloading the latest version of Neovim...') + os.execute('curl -L -o nvim-linux64.tar.gz https://github.com/neovim/neovim/releases/latest/download/nvim-linux64.tar.gz') + append_line('Download complete.') + + -- Extract the downloaded archive + append_line('Extracting the downloaded archive...') + os.execute('tar xzvf nvim-linux64.tar.gz') + append_line('Extraction complete.') + + -- Replace the existing Neovim installation with the new version + append_line('Replacing the existing Neovim installation...') + os.execute('rm -rf $HOME/nvim') + os.execute('mv nvim-linux64 $HOME/nvim') + append_line('Update complete.') + + -- Clean up the downloaded file + append_line('Cleaning up the downloaded file...') + os.execute('rm nvim-linux64.tar.gz') + append_line('Cleanup complete.') + + -- Close the floating window after a delay + vim.defer_fn(function() + vim.api.nvim_win_close(winid, true) + end, 5000) -- Adjust the delay as needed +end + +-- Bind a keymap to the update_neovim function (optional) +vim.api.nvim_set_keymap('n', '<leader>U', '<cmd> lua require("user.mods").Update_neovim()<CR>', { noremap = true, silent = true }) + +-------------------------------------------------- + +-- Fix or suppress closing nvim error message (/src/unix/core.c:147: uv_close: Assertion `!uv__is_closing(handle)' failed.) +vim.api.nvim_create_autocmd({ 'VimLeave' }, { + callback = function() + vim.fn.jobstart('!notify-send 2>/dev/null &', { detach = true }) + end, +}) + +-------------------------------------------------- + +-- Rooter +--vim.cmd([[autocmd BufEnter * lua vim.cmd('Rooter')]]) + +-------------------------------------------------- + +-- Nvim-tree +local modifiedBufs = function(bufs) -- nvim-tree is also there in modified buffers so this function filter it out + local t = 0 + for k, v in pairs(bufs) do + if v.name:match('NvimTree_') == nil then + t = t + 1 + end + end + return t +end + +-- Deleting current file opened behaviour +function M.DeleteCurrentBuffer() + local cbn = vim.api.nvim_get_current_buf() + local buffers = vim.fn.getbufinfo({ buflisted = true }) + local size = #buffers + local idx = 0 + + for n, e in ipairs(buffers) do + if e.bufnr == cbn then + idx = n + break -- Exit loop as soon as we find the buffer + end + end + + if idx == 0 then + return + end + + if idx == size then + vim.cmd('bprevious') + else + vim.cmd('bnext') + end + + vim.cmd('silent! bdelete ' .. cbn) + + -- Open a new blank window + vim.cmd('silent! enew') -- Opens a new vertical split + -- OR + -- vim.cmd("new") -- Opens a new horizontal split + -- Delay before opening a new split + --vim.defer_fn(function() + -- vim.cmd("enew") -- Opens a new vertical split + --end, 100) -- Adjust the delay as needed (in milliseconds) + -- Delay before closing the nvim-tree window +end + +vim.cmd([[autocmd FileType NvimTree lua require("user.mods").DeleteCurrentBuffer()]]) + +-- On :bd nvim-tree should behave as if it wasn't opened +vim.api.nvim_create_autocmd('BufEnter', { + nested = true, + callback = function() + -- Only 1 window with nvim-tree left: we probably closed a file buffer + if #vim.api.nvim_list_wins() == 1 and require('nvim-tree.utils').is_nvim_tree_buf() then + local api = require('nvim-tree.api') + -- Required to let the close event complete. An error is thrown without this. + vim.defer_fn(function() + -- close nvim-tree: will go to the last buffer used before closing + api.tree.toggle({ find_file = true, focus = true }) + -- re-open nivm-tree + api.tree.toggle({ find_file = true, focus = true }) + -- nvim-tree is still the active window. Go to the previous window. + vim.cmd('wincmd p') + end, 0) + end + end, +}) + +-- Dismiss notifications when opening nvim-tree window +local function isNvimTreeOpen() + local win = vim.fn.win_findbuf(vim.fn.bufnr('NvimTree')) + return vim.fn.empty(win) == 0 +end + +function M.DisableNotify() + if isNvimTreeOpen() then + require('notify').dismiss() + end +end + +vim.cmd([[ + autocmd! WinEnter,WinLeave * lua require('user.mods').DisableNotify() +]]) + +-------------------------------------------------- + +-- Toggle Dashboard +function M.toggle_dashboard() + if vim.bo.filetype == 'dashboard' then + vim.cmd('bdelete') + else + vim.cmd('Dashboard') + end +end + +-------------------------------------------------- + +-- Helper function to suppress errors +local function silent_execute(cmd) + vim.fn['serverlist']() -- Required to prevent 'Press ENTER' prompt + local result = vim.fn.system(cmd .. ' 2>/dev/null') + vim.fn['serverlist']() + return result +end + +-------------------------------------------------- + +-- Toggle Codi +-- Define a global variable to track Codi's state +local is_codi_open = false + +function M.toggleCodi() + if is_codi_open then + -- Close Codi + vim.cmd('Codi!') + is_codi_open = false + else + -- Open Codi + vim.cmd('Codi') + is_codi_open = true + end +end + +-------------------------------------------------- + +---- Function to create or toggle a scratch buffer +local scratch_buf = nil -- Store the scratch buffer globally +local scratch_win = nil -- Store the scratch window globally +local scratch_date = os.date('%Y-%m-%d') +local scratch_dir = vim.fn.expand('~/notes/private') +local scratch_file = 'scratch-' .. scratch_date .. '.md' + +function M.Scratch(Split_direction) + -- Check if the directory exists, and create it if it doesn't + if vim.fn.isdirectory(scratch_dir) == 0 then + vim.fn.mkdir(scratch_dir, 'p') + end + + -- Determine the window type based on Split_direction + local current_window_type = 'float' + if Split_direction == 'float' then + current_window_type = 'float' + elseif Split_direction == 'vertical' then + current_window_type = 'vertical' + elseif Split_direction == 'horizontal' then + current_window_type = 'horizontal' + end + + local file_path = scratch_dir .. '/' .. scratch_file + + if scratch_win and vim.api.nvim_win_is_valid(scratch_win) then + -- Window exists, save buffer to file and close it + WriteScratchBufferToFile(scratch_buf, file_path) + vim.cmd(':w!') + vim.api.nvim_win_close(scratch_win, true) + scratch_win = nil + else + if scratch_buf and vim.api.nvim_buf_is_valid(scratch_buf) then + -- Buffer exists, reuse it + OpenScratchWindow(scratch_buf, current_window_type) + else + -- Buffer doesn't exist, create it and load the file if it exists + scratch_buf = OpenScratchBuffer(file_path) + OpenScratchWindow(scratch_buf, current_window_type) + end + end +end + +function WriteScratchBufferToFile(buf, file_path) + local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false) + local content = table.concat(lines, '\n') + local escaped_file_path = vim.fn.fnameescape(file_path) + + -- Write the buffer content to the file + local file = io.open(escaped_file_path, 'w') + if file then + file:write(content) + file:close() + end +end + +function OpenScratchBuffer(file_path) + local buf = vim.api.nvim_create_buf(true, false) + + -- Set the file name for the buffer + local escaped_file_path = vim.fn.fnameescape(file_path) + vim.api.nvim_buf_set_name(buf, escaped_file_path) + + -- Check if the file exists and load it if it does + if vim.fn.filereadable(file_path) == 1 then + local file_contents = vim.fn.readfile(file_path) + vim.api.nvim_buf_set_lines(buf, 0, -1, true, file_contents) + else + -- Insert initial content + vim.api.nvim_buf_set_lines(buf, 0, -1, true, { + '# Quick Notes - ' .. scratch_date, + '--------------------------', + '', + }) + + -- Save the initial content to the file + vim.cmd(':w') + end + + return buf +end + +function OpenScratchWindow(buf, current_window_type) + if current_window_type == 'float' then + local opts = { + relative = 'win', + width = 120, + height = 10, + border = 'single', + row = 20, + col = 20, + } + scratch_win = vim.api.nvim_open_win(buf, true, opts) + -- Go to the last line of the buffer + vim.api.nvim_win_set_cursor(0, { vim.api.nvim_buf_line_count(buf), 1 }) + elseif current_window_type == 'vertical' then + vim.cmd('vsplit') + vim.api.nvim_win_set_buf(0, buf) + scratch_win = 0 + elseif current_window_type == 'horizontal' then + vim.cmd('split') + vim.api.nvim_win_set_buf(0, buf) + scratch_win = 0 + end +end + +-------------------------------------------------- + +-- Intercept file open +local augroup = vim.api.nvim_create_augroup('user-autocmds', { clear = true }) +local intercept_file_open = true +vim.api.nvim_create_user_command('InterceptToggle', function() + intercept_file_open = not intercept_file_open + local intercept_state = '`Enabled`' + if not intercept_file_open then + intercept_state = '`Disabled`' + end + vim.notify('Intercept file open set to ' .. intercept_state, vim.log.levels.INFO, { + title = 'Intercept File Open', + ---@param win integer The window handle + on_open = function(win) + vim.api.nvim_buf_set_option(vim.api.nvim_win_get_buf(win), 'filetype', 'markdown') + end, + }) +end, { desc = 'Toggles intercepting BufNew to open files in custom programs' }) + +-- NOTE: Add "BufReadPre" to the autocmd events to also intercept files given on the command line, e.g. +-- `nvim myfile.txt` +vim.api.nvim_create_autocmd({ 'BufNew' }, { + group = augroup, + callback = function(args) + ---@type string + local path = args.match + ---@type integer + local bufnr = args.buf + + ---@type string? The file extension if detected + local extension = vim.fn.fnamemodify(path, ':e') + ---@type string? The filename if detected + local filename = vim.fn.fnamemodify(path, ':t') + + ---Open a given file path in a given program and remove the buffer for the file. + ---@param buf integer The buffer handle for the opening buffer + ---@param fpath string The file path given to the program + ---@param fname string The file name used in notifications + ---@param prog string The program to execute against the file path + local function open_in_prog(buf, fpath, fname, prog) + vim.notify(string.format('Opening `%s` in `%s`', fname, prog), vim.log.levels.INFO, { + title = 'Open File in External Program', + ---@param win integer The window handle + on_open = function(win) + vim.api.nvim_buf_set_option(vim.api.nvim_win_get_buf(win), 'filetype', 'markdown') + end, + }) + local mods = require('user.mods') + local nvim_ver = mods.get_nvim_version() + + local version_major, version_minor = string.match(nvim_ver, '(%d+)%.(%d+)') + version_major = tonumber(version_major) + version_minor = tonumber(version_minor) + + if version_major > 0 or (version_major == 0 and version_minor >= 10) then + vim.system({ prog, fpath }, { detach = true }) + else + vim.fn.jobstart({ prog, fpath }, { detach = true }) + end + vim.api.nvim_buf_delete(buf, { force = true }) + end + + local extension_callbacks = { + ['pdf'] = function(buf, fpath, fname) + open_in_prog(buf, fpath, fname, 'zathura') + end, + ['png'] = function(buf, fpath, fname) + open_in_prog(buf, fpath, fname, 'feh') + end, + ['jpg'] = 'png', + ['mp4'] = function(buf, fpath, fname) + open_in_prog(buf, fpath, fname, 'mpv') + end, + ['gif'] = 'mp4', + } + + ---Get the extension callback for a given extension. Will do a recursive lookup if an extension callback is actually + ---of type string to get the correct extension + ---@param ext string A file extension. Example: `png`. + ---@return fun(bufnr: integer, path: string, filename: string?) extension_callback The extension callback to invoke, expects a buffer handle, file path, and filename. + local function extension_lookup(ext) + local callback = extension_callbacks[ext] + if type(callback) == 'string' then + callback = extension_lookup(callback) + end + return callback + end + + if extension ~= nil and not extension:match('^%s*$') and intercept_file_open then + local callback = extension_lookup(extension) + if type(callback) == 'function' then + callback(bufnr, path, filename) + end + end + end, +}) + +-------------------------------------------------- + +-- ... +return M diff --git a/.config/nvim/lua/user/opts.lua b/.config/nvim/lua/user/opts.lua new file mode 100644 index 0000000..c724710 --- /dev/null +++ b/.config/nvim/lua/user/opts.lua @@ -0,0 +1,303 @@ +--[[ opts.lua ]] + +-- Environment +--vim.opt.shell = "zsh" -- +vim.o.updatetime = 250 +vim.o.shell = '/bin/zsh' +vim.scriptencoding = 'utf-8' -- +vim.opt.encoding = 'utf-8' -- +vim.opt.fileencoding = 'utf-8' -- +vim.g.python3_host_prog = '/usr/bin/python3' -- +vim.g.loaded_python3_provider = 1 -- +vim.g.sh_noisk = 1 -- iskeyword word boundaries when editing a 'sh' file +vim.o.autochdir = true +--vim.o.writeany= true + +-- Clipboard +vim.opt.clipboard:append({ 'unnamedplus' }) -- Install xclip or this will slowdown startup + +-- Behaviour +vim.opt.backspace = { 'start', 'eol', 'indent' } -- Make backspace work as you would expect. +vim.opt.hidden = true -- Switch between buffers without having to save first. +vim.opt.splitbelow = true -- make split put the new buffer below the current buffer +vim.opt.splitright = true -- make vsplit put the new buffer on the right of the current buffer +vim.opt.scrolloff = 8 -- +vim.opt.sidescrolloff = 8 -- how many lines to scroll when using the scrollbar +vim.opt.autoread = true -- reload files if changed externally +vim.opt.display = 'lastline' -- Show as much as possible of the last line. +vim.opt.inccommand = 'split' -- +vim.opt.ttyfast = true -- Faster redrawing. +vim.opt.lazyredraw = false -- Only redraw when necessary +vim.opt.keywordprg = ':help' -- :help options +vim.opt.ruler = true -- +vim.opt.errorbells = false -- +vim.opt.list = true -- Show non-printable characters. +vim.opt.showmatch = true -- +vim.opt.matchtime = 3 -- +vim.opt.showbreak = 'โช ' -- +vim.opt.linebreak = true -- +vim.opt.exrc = true -- +--vim.opt.autochdir = true -- or use this to use <:e> to create a file in current directory +vim.opt.autoread = true -- if a file is changed outside of vim, automatically reload it without asking +--vim.opt.notimeout = true -- Timeout on keycodes and not mappings +vim.opt.ttimeout = true -- Makes terminal vim work sanely +vim.opt.ttimeoutlen = 10 -- +--vim.opt.timeoutlen = 100 -- time to wait for a mapped sequence to complete (in milliseconds) +--vim.cmd([[set diffopt = vertical = true]]) -- diffs are shown side-by-side not above/below + +-- Indent/tab +vim.opt.breakindent = true -- +vim.opt.autoindent = true -- Indent according to previous line. +vim.opt.copyindent = true -- Copy indent from the previous line +vim.opt.smarttab = false -- +vim.opt.tabstop = 2 -- +vim.opt.expandtab = true -- Indent according to previous line. +--vim.opt.expandtab = true -- Use spaces instead of tabs. +vim.opt.softtabstop = 2 -- Tab key indents by 2 spaces. +vim.opt.shiftwidth = 2 -- >> indents by 2 spaces. +vim.opt.shiftround = true -- >> indents to next multiple of 'shiftwidth'. +vim.opt.smartindent = true -- smart indent + +-- Column/statusline/Cl +vim.opt.number = true -- +vim.opt.title = true -- +--vim.opt.colorcolumn = "+1" -- +vim.opt.signcolumn = 'yes:1' -- always show the sign column +--vim.opt.signcolumn = "yes:" .. vim.o.numberwidth +--vim.opt.signcolumn = "number" +--vim.opt.signcolumn = "no" -- +vim.opt.laststatus = 3 -- " Always show statusline. +vim.opt.showmode = true -- Show current mode in command-line, example: -- INSERT -- mode +vim.opt.showcmd = true -- Show the command in the status bar +vim.opt.cmdheight = 1 -- +--vim.opt.cmdheight = 0 -- +vim.opt.report = 0 -- Always report changed lines. +--local autocmd = vim.api.nvim_create_autocmd +--autocmd("bufenter", { +-- pattern = "*", +-- callback = function() +-- if vim.bo.ft ~= "terminal" then +-- vim.opt.statusline = "%!v:lua.require'ui.statusline'.run()" +-- else +-- vim.opt.statusline = "%#normal# " +-- end +-- end, +--}) +---- With vertical splits, the statusline would still show up at the +---- bottom of the split. A quick fix is to just set the statusline +---- to empty whitespace (it can't be an empty string because then +---- it'll get replaced by the default stline). +--vim.opt.stl = " " + +-- Backup/undo/swap +local prefix = vim.env.XDG_CONFIG_HOME or vim.fn.expand('~/.config') +--vim.opt.undodir = os.getenv("HOME") .. "/.vim/undodir" +vim.opt.undodir = { prefix .. '/nvim/tmp/.undo//' } +vim.opt.directory = { prefix .. '/nvim/tmp/.swp//' } +vim.opt.backupdir = { prefix .. '/nvim/tmp/.backup//' } +vim.opt.undofile = true -- +vim.opt.swapfile = true -- +vim.opt.backup = true -- +--vim.opt.backupcopy = +-- Add timestamp as extension for backup files +vim.api.nvim_create_autocmd('BufWritePre', { + group = vim.api.nvim_create_augroup('timestamp_backupext', { clear = true }), + desc = 'Add timestamp to backup extension', + pattern = '*', + callback = function() + vim.opt.backupext = '-' .. vim.fn.strftime('%Y%m%d%H%M') + end, +}) + +-- Format +--vim.opt.textwidth = 80 -- +vim.opt.isfname:append('@-@') +vim.cmd([[let &t_Cs = "\e[4:3m"]]) -- Undercurl +vim.cmd([[let &t_Ce = "\e[4:0m"]]) -- +vim.opt.path:append({ '**' }) -- Finding files - Search down into subfolder +vim.cmd('set whichwrap+=<,>,[,],h,l') -- +vim.cmd([[set iskeyword+=-]]) -- +--vim.cmd([[set formatoptions-=cro]]) -- TODO: this doesn't seem to work +vim.opt.formatoptions = vim.opt.formatoptions + - 't' -- wrap with text width + + 'c' -- wrap comments + + 'r' -- insert comment after enter + - 'o' -- insert comment after o/O + - 'q' -- allow formatting of comments with gq + - 'a' -- format paragraphs + + 'n' -- recognized numbered lists + - '2' -- use indent of second line for paragraph + + 'l' -- long lines are not broken + + 'j' -- remove comment when joining lines +vim.opt.wrapscan = true -- " Searches wrap around end-of-file. +--vim.wo.number = true -- +--vim.opt.wrap = false -- No Wrap lines +--vim.opt.foldmethod = 'manual' -- +--vim.opt.foldmethod = "expr" -- +vim.opt.foldmethod = 'manual' +vim.opt.foldlevel = 3 +vim.opt.confirm = false +--vim.opt.shortmess:append("sI") +--vim.opt.shortmess = "a" +--vim.opt.shortmess = "sI" +--vim.o.shortmess = vim.o.shortmess:gsub('s', '') +vim.opt.shortmess = table.concat({ -- Use abbreviations and short messages in command menu line. + 'f', -- Use "(3 of 5)" instead of "(file 3 of 5)". + 'i', -- Use "[noeol]" instead of "[Incomplete last line]". + 'l', -- Use "999L, 888C" instead of "999 lines, 888 characters". + 'm', -- Use "[+]" instead of "[Modified]". + 'n', -- Use "[New]" instead of "[New File]". + 'r', -- Use "[RO]" instead of "[readonly]". + 'w', -- Use "[w]", "[a]" instead of "written", "appended". + 'x', -- Use "[dos]", "[unix]", "[mac]" instead of "[dos format]", "[unix format]", "[mac format]". + 'o', -- Overwrite message for writing a file with subsequent message. + 'O', -- Message for reading a file overwrites any previous message. + 's', -- Disable "search hit BOTTOM, continuing at TOP" such messages. + 't', -- Truncate file message at the start if it is too long. + 'T', -- Truncate other messages in the middle if they are too long. + 'I', -- Don't give the :intro message when starting. + 'c', -- Don't give ins-completion-menu messages. + 'F', -- Don't give the file info when editing a file. +}) +vim.opt.fillchars = { + horiz = 'โ', + horizup = 'โด', + horizdown = 'โฌ', + vert = 'โ', + vertleft = 'โค', + vertright = 'โ', + verthoriz = 'โผ', + foldopen = '๏', + foldsep = 'โ', + foldclose = '๏
', + fold = 'โ', + eob = ' ', + --diff = "โ", + diff = 'โ', + msgsep = 'โ', + --msgsep = "โพ", +} +vim.opt.listchars = { tab = 'โธ ', trail = 'ยท' } -- +--vim.opt.fillchars:append({ eob = " " }) -- remove the ~ from end of buffer +vim.opt.modeline = true -- +vim.opt.modelines = 3 -- modelines (comments that set vim options on a per-file basis) +--vim.opt.modelineexpr = true +--vim.opt.nofoldenable = true -- turn folding off +--vim.opt.foldenable = false -- turn folding off +vim.o.showtabline = 2 + +-- Highlights +vim.opt.incsearch = true -- Highlight while searching with / or ?. +vim.opt.hlsearch = true -- Keep matches highlighted. +vim.opt.ignorecase = true -- ignore case in search patterns UNLESS /C or capital in search +vim.opt.smartcase = true -- smart case +vim.opt.synmaxcol = 200 -- Only highlight the first 200 columns. +vim.opt.winblend = 30 +--vim.opt.winblend = 5 +vim.opt.wildoptions = 'pum' -- +--vim.opt.pumblend = 5 -- +vim.opt.pumblend = 12 -- +--vim.opt.pumblend=15 +vim.opt.pumheight = 10 -- pop up menu height + +-- Better Completion +vim.opt.complete = { '.', 'w', 'b', 'u', 't' } -- +--vim.opt.completeopt = { "longest,menuone,preview" } -- +vim.opt.completeopt = { 'menu', 'menuone', 'noselect' } +--vim.opt.completeopt = { "menuone", "noselect" } -- mostly just for cmp +--vim.opt.completeopt = { "menu", "menuone", "noselect" } -- + +-- Wildmenu completion -- +vim.opt.wildmenu = true -- +vim.opt.wildmode = { 'list:longest' } -- +vim.opt.wildignore:append({ '.hg', '.git', '.svn' }) -- Version control +vim.opt.wildignore:append({ '*.aux', '*.out', '*.toc' }) -- LaTeX intermediate files +vim.opt.wildignore:append({ '*.jpg', '*.bmp', '*.gif', '*.png', '*.jpeg' }) -- binary images +vim.opt.wildignore:append({ '*.o', '*.obj', '*.exe', '*.dll', '*.manifest' }) -- compiled object files +vim.opt.wildignore:append({ '*.spl' }) -- compiled spelling word lists +vim.opt.wildignore:append({ '*.sw?' }) -- Vim swap files +vim.opt.wildignore:append({ '*.DS_Store' }) -- OSX bullshit +vim.opt.wildignore:append({ '*.luac' }) -- Lua byte code +vim.opt.wildignore:append({ 'migrations' }) -- Django migrations +vim.opt.wildignore:append({ '*.pyc' }) -- Python byte code +vim.opt.wildignore:append({ '*.orig' }) -- Merge resolution files +vim.opt.wildignore:append({ '*/node_modules/*' }) -- + +-- Shada +vim.opt.shada = "!,'1000,f1,<1000,s100,:1000,/1000,h" + +-- Sessions +vim.opt.sessionoptions = 'blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal' +--vim.opt.sessionoptions = "curdir,folds,help,options,tabpages,winsize,winpos,terminal,globals" -- +--vim.opt.sessionoptions = "buffers,curdir,folds,help,tabpages,winsize,winpos,terminal" +--vim.opt.sessionoptions:remove({ "blank", "buffers", "globals" }) + +-- Netrw file tree +vim.g.netrw_browse_split = 0 +vim.g.netrw_banner = 0 +vim.g.netrw_winsize = 25 + +-- " Load indent files, to automatically do language-dependent indenting. +--vim.cmd([[ +-- "filetype plugin indent on +--]]) +vim.cmd('filetype plugin on') +vim.cmd('filetype indent off') + +-- Let clipboard register be + +vim.cmd([[ + let g:clipbrdDefaultReg = '+' +]]) + +--vim.cmd([[ +-- "autocmd BufEnter * :syntax sync fromstart +-- "syntax enable +-- "set nocompatible +-- "autocmd FileType lua set comments=s1:---,m:--,ex:-- +--]]) + +-- Fast macros without lazyredraw +vim.cmd([[ + set re=0 + nnoremap @ <cmd>execute "noautocmd norm! " . v:count1 . "@" . getcharstr()<cr> + xnoremap @ :<C-U>execute "noautocmd '<,'>norm! " . v:count1 . "@" . getcharstr()<cr> +]]) + +-- Stop annoying auto commenting on new lines +vim.cmd([[ + augroup annoying + au! + au BufEnter * set fo-=c fo-=r fo-=o + augroup end +]]) + +-- Cursorline +vim.cmd([[ " Only show cursorline in the current window and in normal mode + augroup cline + au! + au WinLeave,InsertEnter * set nocursorline + au WinEnter,InsertLeave * set cursorline + augroup END +]]) +vim.opt.cursorline = true -- +vim.opt.guicursor = 'i:ver100,r:hor100' -- + +-- Trailing whitespace +vim.cmd([[ " Only show in insert mode + augroup trailing + au! + au InsertEnter * :set listchars-=trail:โด + au InsertLeave * :set listchars+=trail:โด + augroup END +]]) + +-- Line Return +vim.cmd([[ " Return to the same line when we reopen a file + augroup line_return + au! + au BufReadPost * + \ if line("'\"") > 0 && line("'\"") <= line("$") | + \ execute 'normal! g`"zvzz' | + \ endif + augroup END +]]) diff --git a/.config/nvim/lua/user/pack.lua b/.config/nvim/lua/user/pack.lua new file mode 100644 index 0000000..2f3e1e8 --- /dev/null +++ b/.config/nvim/lua/user/pack.lua @@ -0,0 +1,375 @@ +local fn = vim.fn + +-------------------------------------------------- + +-- Automatically install packer +local install_path = fn.stdpath('data') .. '/site/pack/packer/start/packer.nvim' +if fn.empty(fn.glob(install_path)) > 0 then + PACKER_BOOTSTRAP = fn.system({ + 'git', + 'clone', + '--depth', + '1', + 'https://github.com/wbthomason/packer.nvim', + install_path, + }) + print('Installing packer, please close and reopen Neovim...') + vim.cmd([[packadd packer.nvim]]) +end + +-------------------------------------------------- + +-- Autocommand that reloads neovim whenever you save this file +vim.cmd([[ + augroup packer_user_config + autocmd! + autocmd BufWritePost pack.lua source <afile> | PackerSync + augroup end +]]) + +-------------------------------------------------- + +-- Use a protected call so don't error out on first use +local status_ok, packer = pcall(require, 'packer') +if not status_ok then + return +end + +-------------------------------------------------- + +-- Have packer use a popup window and set a maximum number of jobs +packer.init({ + auto_reload_compiled = true, + --max_jobs = 90, + display = { + open_fn = function() + return require('packer.util').float({ border = 'rounded' }) + end, + }, +}) + +-------------------------------------------------- + +-- Install plugins here +return packer.startup(function(use) + -- Defaults + use('wbthomason/packer.nvim') -- Have packer manage itself (package manager) + use('nvim-lua/plenary.nvim') -- Useful lua functions used by lots of plugins + use('lewis6991/impatient.nvim') -- Faster loading/startup times + + -- Tree-sitter + use({ 'nvim-treesitter/nvim-treesitter', run = ':TSUpdate' }) -- For language parsing, examples: highlighting, folding, jumping, refactoring... + use('nvim-treesitter/nvim-treesitter-refactor') -- Refactor module for nvim-treesitter + + -- lsp + use('williamboman/mason.nvim') -- Package manager to install and manage LSP servers, DAP servers, linters and formatters + use('neovim/nvim-lspconfig') -- Collection of LSP configs + use('williamboman/mason-lspconfig.nvim') -- Bridges mason.nvim with nvim-lspconfig to help use them together + use({ + 'https://git.sr.ht/~whynothugo/lsp_lines.nvim', + config = function() + require('lsp_lines').setup() + end, + }) + use('rmagatti/goto-preview') + + -- Debugger + use('mfussenegger/nvim-dap') -- Debug Adapter Protocol client implementation for Neovim + use('rcarriga/nvim-dap-ui') -- UI for nvim-dap + --use { "rcarriga/nvim-dap-ui", requires = {"mfussenegger/nvim-dap"} } + use('theHamsta/nvim-dap-virtual-text') + use('gabrielpoca/replacer.nvim') + use('jayp0521/mason-nvim-dap.nvim') + --use({ + -- "jayp0521/mason-nvim-dap.nvim", + -- config = function() + -- require("mason-nvim-dap").setup({ + -- automatic_installation = true, + -- ensure_installed = { "python", "cppdbg", "codelldb" }, + -- }) + -- end, + --}) + + -- Linters/Formatters + use('mhartington/formatter.nvim') + use('jay-babu/mason-null-ls.nvim') + --use({"jayp0521/mason-null-ls.nvim", + -- config = function() + -- require('mason-null-ls.nvim').setup({ + -- automatic_setup = true, + -- }) + -- end + --}) + use({ + 'jose-elias-alvarez/null-ls.nvim', -- Provides LSP: linters, formatters, diagnostics, code actions and etc... + requires = { 'jay-babu/mason-null-ls.nvim' }, + }) + + -- Completion + use('hrsh7th/nvim-cmp') -- Completion engine plugin + use('hrsh7th/cmp-nvim-lsp') -- Completion source for nvim-lsp + use('hrsh7th/cmp-buffer') -- Completion source for content of current buffer + use('hrsh7th/cmp-path') -- Completion source for paths + use('hrsh7th/cmp-cmdline') -- Completion source for command-line + use('petertriho/cmp-git') -- Completion source for git + use('tamago324/cmp-zsh') -- Completion source for zsh + use('f3fora/cmp-spell') -- Completion source for spell-checking + use('hrsh7th/cmp-calc') -- Completion source for math calculation + use('saadparwaiz1/cmp_luasnip') -- Completion source for snippets, specifically for luasnip + use('hrsh7th/cmp-nvim-lsp-signature-help') -- Completion source for displaying function signatures with the current parameter emphasized + use('rcarriga/cmp-dap') + + -- Snippets + use('L3MON4D3/LuaSnip') -- Snippet engine + use('rafamadriz/friendly-snippets') -- Collection of snippets to use + + -- Git + use('tpope/vim-fugitive') -- + --use("dinhhuy258/git.nvim") -- For git blame & browse + use('kdheepak/lazygit.nvim') -- Terminal UI for git commands + use('lewis6991/gitsigns.nvim') -- Git decorations + + -- File explorer/fuzzy finder + use('kyazdani42/nvim-tree.lua') -- File explorer + use('ibhagwan/fzf-lua') -- Fuzzy finder + use('ThePrimeagen/harpoon') + --use("nvim-telescope/telescope.nvim") -- Fuzzy finder with lots of features/extendabilities + use({ + 'nvim-telescope/telescope.nvim', + branch = '0.1.x', + --config = function() + -- require('plugins.telescope').setup() + --end, + requires = { + 'nvim-lua/plenary.nvim', + 'nvim-telescope/telescope-live-grep-args.nvim', + 'nvim-telescope/telescope-file-browser.nvim', + { 'nvim-telescope/telescope-fzf-native.nvim', run = 'make' }, + }, + }) + use({ 'nvim-telescope/telescope-fzf-native.nvim', run = 'make' }) -- Support fzf syntax/algorithm + use('nvim-telescope/telescope-ui-select.nvim') -- + use('nvim-telescope/telescope-project.nvim') -- + use('nvim-telescope/telescope-media-files.nvim') -- + use('nvim-telescope/telescope-file-browser.nvim') -- + use({ 'nvim-telescope/telescope-symbols.nvim', after = 'telescope.nvim' }) -- Search emoji(s) and other symbols + use('nvim-telescope/telescope-dap.nvim') + use('axkirillov/telescope-changed-files') -- + use('smartpde/telescope-recent-files') + use('rmagatti/auto-session') + use('rmagatti/session-lens') + + -- UX + use('folke/neodev.nvim') + use({ + 'numToStr/Navigator.nvim', -- Navigate between Tmux and Nvim + config = function() + require('Navigator').setup() + end, + }) + use({ 'tpope/vim-eunuch', cmd = { 'Rename', 'Delete', 'Mkdir' } }) -- Handy unix commands inside Vim (Rename, Move etc.) + --use("tpope/vim-surround") -- + --use("tpope/vim-obsession") -- + use('tpope/vim-unimpaired') -- + --use("vimpostor/vim-tpipeline") -- + --use("nathom/filetype.nvim") -- + use('mbbill/undotree') + use({ + 'myusuf3/numbers.vim', -- + vim.cmd("let g:numbers_exclude = ['dashboard']"), + }) + use('windwp/nvim-autopairs') -- + use('numToStr/Comment.nvim') -- + use('akinsho/toggleterm.nvim') -- + use('tweekmonster/startuptime.vim') -- + use('qpkorr/vim-bufkill') + use({ + 'ggandor/leap.nvim', -- + config = function() + require('leap').add_default_mappings() + --require("leap").set_default_keymaps() + --vim.keymap.set('n', '-', '<Plug>(leap-forward)', {}) + --vim.keymap.set('n', '_', '<Plug>(leap-backward)', {}) + end, + }) + use({ + 'ggandor/flit.nvim', -- + config = function() + require('flit').setup() + end, + }) + use('folke/which-key.nvim') -- + use('folke/zen-mode.nvim') -- + use('romainl/vim-cool') -- + use('antoinemadec/FixCursorHold.nvim') -- + use({ + 'folke/trouble.nvim', + requires = 'nvim-tree/nvim-web-devicons', + }) + use({ + 'airblade/vim-rooter', -- + --vim.cmd("let g:rooter_change_directory_for_non_project_files = ''"), + --vim.cmd("let g:rooter_change_directory_for_non_project_files = 'current'") + }) + use({ 'michaelb/sniprun', run = 'bash ./install.sh' }) + --use("vim-test/vim-test") -- + --use({ + -- "rcarriga/vim-ultest", -- + -- requires = { "vim-test/vim-test" }, + -- run = ":UpdateRemotePlugins", + -- config = function() + -- require("plugins.ultest") + -- end, + --}) + --use({"rcarriga/neotest", + -- config = function() + -- require("neotest").setup() + --end, + --}) + use({ + 'nvim-neotest/neotest', + requires = { + { + 'nvim-neotest/neotest-python', + 'nvim-neotest/neotest-plenary', + 'nvim-neotest/neotest-vim-test', + }, + }, + }) + + -- Colorschemes + use('bluz71/vim-nightfly-guicolors') + use('ayu-theme/ayu-vim') + use('joshdick/onedark.vim') + use('NTBBloodbath/doom-one.nvim') + use('nyngwang/nvimgelion') + use('projekt0n/github-nvim-theme') + use({ + 'folke/tokyonight.nvim', + config = function() + require('tokyonight').setup({ + transparent = true, + dim_inactive = false, + }) + end, + }) + + -- UI + use('kyazdani42/nvim-web-devicons') -- + use('onsails/lspkind-nvim') -- + use({ 'kevinhwang91/nvim-ufo', requires = 'kevinhwang91/promise-async' }) -- Fold code + use({ + 'luukvbaal/statuscol.nvim', + config = function() + local builtin = require('statuscol.builtin') + require('statuscol').setup({ + relculright = true, + segments = { + { text = { builtin.foldfunc }, click = 'v:lua.ScFa' }, + { text = { '%s' }, click = 'v:lua.ScSa' }, + { text = { builtin.lnumfunc, ' ' }, click = 'v:lua.ScLa' }, + }, + }) + end, + }) + use({ + 'glepnir/dashboard-nvim', + --event = 'VimEnter', + requires = { 'nvim-tree/nvim-web-devicons' }, + }) + use('rcarriga/nvim-notify') -- Notification plugin + use('karb94/neoscroll.nvim') -- Faster/smooth scrolling + --use("MunifTanjim/prettier.nvim") -- Prettier plugin for Neovim's built-in LSP client + use({ + 'norcalli/nvim-colorizer.lua', -- colorize hexa and rgb strings + cmd = { 'ColorizerToggle', 'ColorizerAttachToBuffer' }, + config = function() + require('colorizer').setup({ + --'*'; + user_default_options = { + RGB = true, + RRGGBB = true, + names = false, + RRGGBBAA = false, + css = false, + css_fn = true, + mode = 'foreground', + }, + }) + end, + }) + use({ + 'j-hui/fidget.nvim', + tag = 'legacy', + }) -- UI to show nvim-lsp progress + use('metakirby5/codi.vim') + use({ + 'simrat39/symbols-outline.nvim', -- + config = function() + require('symbols-outline').setup({ + auto_close = true, + }) + end, + }) + use({ + 'kosayoda/nvim-lightbulb', -- + requires = 'antoinemadec/FixCursorHold.nvim', + }) + use({ + 'SmiteshP/nvim-navic', -- Statusline/Winbar component that uses LSP to show current code context + requires = 'neovim/nvim-lspconfig', + }) + use({ + 'rebelot/heirline.nvim', -- Statusline that is highly configurable + --requires = 'kyazdani42/nvim-web-devicons', + --event = 'VimEnter', + }) + + -- Language specific tools + use('simrat39/rust-tools.nvim') -- Rust tooling ecosystem + use({ + 'saecki/crates.nvim', -- + requires = { 'nvim-lua/plenary.nvim' }, + config = function() + require('crates').setup() + end, + }) + use({ + 'akinsho/flutter-tools.nvim', + requires = { + 'nvim-lua/plenary.nvim', + 'stevearc/dressing.nvim', -- optional for vim.ui.select + }, + config = function() + require('flutter-tools').setup({ + debugger = { + enabled = true, + run_via_dap = true, + }, + }) + end, + }) + use({ + 'iamcco/markdown-preview.nvim', -- Markdown Preview + run = function() + vim.fn['mkdp#util#install']() + end, + vim.cmd("let g:mkdp_auto_close = 0"), + }) + use({ + 'ellisonleao/glow.nvim', -- Markdown Preview + config = function() + require('glow').setup({ + style = 'dark', + }) + end, + }) + + -------------------------------------------------- + + -- Automatically set up your configuration after cloning packer.nvim + -- Put this at the end after all plugins + if PACKER_BOOTSTRAP then + require('packer').sync() + end +end) |
