diff options
Diffstat (limited to '')
52 files changed, 1958 insertions, 1210 deletions
diff --git a/lua/.luarc.json b/lua/.luarc.json deleted file mode 100644 index 8d322a3..0000000 --- a/lua/.luarc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "diagnostics.globals": [ - "g", - "o", - "a", - "vim", - ], - "workspace.checkThirdParty": false -} diff --git a/lua/bootstrap.lua b/lua/bootstrap.lua deleted file mode 100644 index f522833..0000000 --- a/lua/bootstrap.lua +++ /dev/null @@ -1,5 +0,0 @@ -local path = vim.fn.stdpath("data").."/site/pack/deps/opt/dep" -if vim.fn.empty(vim.fn.glob(path)) > 0 then - vim.fn.system({ "git", "clone", "--depth=1", "https://git.squi.bid/dep", path }) -end -vim.cmd("packadd dep") diff --git a/lua/conf/auto.lua b/lua/conf/auto.lua deleted file mode 100644 index 0ab1a86..0000000 --- a/lua/conf/auto.lua +++ /dev/null @@ -1,87 +0,0 @@ -local function auto(event, opts) - a.nvim_create_autocmd(event, opts) -end - -local function augroup(name, opts) - opts = opts or {} - opts['clear'] = true - a.nvim_create_augroup(name, opts) -end - -local winchange = augroup('winchange') -local bufcheck = augroup('bufcheck') -local toggles = augroup('toggles') - -auto({ "FocusGained", "TermClose", "TermLeave" }, { - group = bufcheck, - desc = 'Update contents of file.', - command = "checktime", -}) - -auto("VimResized", { - group = winchange, - desc = 'Resize splits when window is resized.', - callback = function() - local current_tab = vim.fn.tabpagenr() - vim.cmd("tabdo wincmd =") - vim.cmd("tabnext " .. current_tab) - end, -}) - -auto('TextYankPost', { - group = bufcheck, - pattern = '*', - desc = 'Highlight on yank.', - callback = function() - vim.highlight.on_yank{ timeout = 250 } - end -}) - -auto('BufRead', { - pattern = '*', - group = bufcheck, - desc = 'Return to the last place the buffer was closed in.', - callback = function() vim.cmd([[call setpos(".", getpos("'\""))]]) end -}) - -auto('FileType', { - pattern = { 'gitcommit', 'markdown' }, - desc = 'Spell checking and wrapping in commit buffers and markdown files.', - callback = function() - vim.opt_local.wrap = true - vim.opt_local.spell = true - end -}) - -auto('BufWritePre', { - pattern = '*', - group = bufcheck, - desc = 'Basically mkdir -p.', - callback = function(ctx) - if ctx.match:match("^%w%w+://") then return end - local dir = vim.fn.fnamemodify(ctx.file, ':p:h') - vim.fn.mkdir(dir, 'p') - end -}) - -auto('WinLeave', { - desc = 'Unset cursorline', - group = toggles, - callback = function() vim.opt.cursorline = false end -}) - -auto('WinEnter', { - desc = 'Set cursorline', - group = toggles, - callback = function() - if vim.bo.filetype ~= 'alpha' then - vim.opt.cursorline = true - end - end -}) - -auto('ColorScheme', { - desc = 'Update statusline on colorscheme change', - group = winchange, - callback = function() require('el').reset_windows() end -}) diff --git a/lua/conf/autos.lua b/lua/conf/autos.lua new file mode 100644 index 0000000..51ed58a --- /dev/null +++ b/lua/conf/autos.lua @@ -0,0 +1,50 @@ +local misc = require('core.misc') +local auto, augroup = misc.auto, misc.augroup + +-- auto commands which interact with bufferes without modifying them +local bufcheck = augroup('bufcheck') +-- auto commands which modify things on the filesystem +local fsmod = augroup('fsmod') + +auto('FocusGained', { + group = bufcheck, + desc = 'Update contents of file.', + command = 'checktime', +}) + +auto('TextYankPost', { + pattern = '*', + group = bufcheck, + desc = 'Highlight on yank.', + callback = function() + vim.highlight.on_yank { timeout = 250 } + end +}) + +auto('BufRead', { + pattern = '*', + group = bufcheck, + desc = 'Return to the last place the buffer was closed in.', + callback = function() + vim.cmd([[call setpos(".", getpos("'\""))]]) + vim.api.nvim_input('zz') + end +}) + +auto('BufWritePre', { + pattern = '*', + group = fsmod, + desc = 'remove trailing spaces on file save', + command = [[%s/\s\+$//e]] +}) + +auto('BufWritePre', { + pattern = '*', + group = fsmod, + desc = 'Basically mkdir -p.', + callback = function(ctx) + if ctx.match:match("^%w%w+://") then return end + local dir = vim.fn.fnamemodify(ctx.file, ':p:h') + vim.fn.mkdir(dir, 'p') + end +}) diff --git a/lua/conf/binds.lua b/lua/conf/binds.lua index 42c609e..2031852 100644 --- a/lua/conf/binds.lua +++ b/lua/conf/binds.lua @@ -1,25 +1,11 @@ -local conf = require('core.conf') +local misc = require('core.misc') +local map, auto = misc.map, misc.auto -local function map(mode, bind, cmd, opts) - opts = opts or {} - opts['noremap'] = true - opts['silent'] = true - - if type(bind) == 'table' then - for i in pairs(bind) do - vim.keymap.set(mode, bind[i], cmd, opts) - end - elseif type(bind) == 'string' then - vim.keymap.set(mode, bind, cmd, opts) - end -end - --- vim binds ------------------------------------------------------------------ -g.mapleader = ' ' -- set leader key +-- vim binds +vim.g.mapleader = ' ' -- set leader key map('x', '<leader>p', [["_dP]], { desc = 'Greatest remap of all time.' }) map('n', '<esc>', ':nohlsearch<Bar>:echo<CR>', { desc = 'Clear search.' }) -map('t', '<esc>', '<C-\\><C-n>', { desc = 'make <esc> work in terminals.' }) -- move selected text up/down map('v', '<S-k>', ":m '<-2<CR>gv=gv", { desc = 'Move selected text up.' }) map('v', '<S-j>', ":m '>+1<CR>gv=gv", { desc = 'Move selected text down.' }) @@ -45,22 +31,7 @@ map('n', '<leader>x', function() -- execute order 111 else vim.notify("File doesn't exist", vim.log.levels.INFO, { title = misc.appid }) end -end) - --- add some keybinds to the file view (netrw) -a.nvim_create_autocmd('FileType', { - pattern = 'netrw', - callback = function() - local function bind(lhs, rhs) - vim.keymap.set('n', lhs, rhs, { remap = true, buffer = true }) - end - bind('h', '-^') -- Go up a directory - bind('l', '<CR>') -- Go down a directory / open a file - bind('.', 'gh') -- Toggle hidden files - bind('P', '<C-w>z') -- Close preview window - bind('<esc>', '<cmd>q<CR>') -- Close netrw - end -}) +end, { desc = 'toggle executable flag of the file' }) -- tabs map('n', '[]', '<cmd>tabnew<CR>') @@ -68,118 +39,22 @@ map('n', '][', '<cmd>tabc<CR>') map('n', '[[', '<cmd>tabp<CR>') map('n', ']]', '<cmd>tabn<CR>') --- config binds --------------------------------------------------------------- -map('n', '<leader>m', conf.configmenu, { desc = 'Neovim config manager menu', }) - --- plugin binds --------------------------------------------------------------- - --- pretty lsp view -map('n', 'gd', '<CMD>Glance definitions<CR>') -map('n', 'gr', '<CMD>Glance references<CR>') -map('n', 'gy', '<CMD>Glance type_definitions<CR>') -map('n', 'gi', '<CMD>Glance implementations<CR>') - -if pcall(require, "treesj") then - local treesj = require('treesj') -- treesj - map('n', '<leader>j', treesj.toggle) -end - -if pcall(require, "telescope") then - local telebuilt = require('telescope.builtin') -- telescope - -- local telexten = require('telescope').extensions - map('n', '<leader>sf', telebuilt.find_files, { desc = 'Find files.' }) - map('n', '<leader>so', telebuilt.oldfiles, { desc = 'Find old files.' }) - map('n', '<leader>sg', telebuilt.git_files, { desc = 'Find git files.' }) - -- search urls in buffer - map('n', '<leader>su', '<Cmd>UrlView<CR>', { desc = 'Find urls in buffer.' }) - -- search lsp symbols - map('n', '<leader>ss', telebuilt.lsp_document_symbols, - { desc = 'Find LSP Symbols.' }) - -- search for keybinds - map('n', '<leader>sk', telebuilt.keymaps, - { desc = 'Find nvim Keymaps.' }) - -- search for highlights - map('n', '<leader>sh', telebuilt.highlights, - { desc = 'Find nvim Highlights.' }) - -- search for autocommands - map('n', '<leader>sa', telebuilt.autocommands, - { desc = 'Find nvim Autocommands.' }) - -- search for vim options - map('n', '<leader>sv', telebuilt.vim_options, { desc = 'Find vim options.' }) - -- search for string in project - map('n', '<leader>sp', telebuilt.live_grep, { desc = 'Find string in project.' }) - - -- Code Actions (requires telescope) - if pcall(require, "actions-preview") then - map({ "n", "v" }, "<leader>ca", require("actions-preview").code_actions, { - desc = 'preview code actions' - }) +-- good spell suggestion ui +-- (stolen from https://github.com/neovim/neovim/pull/25833) +local spell_on_choice = vim.schedule_wrap(function(_, idx) + if type(idx) == 'number' then + vim.cmd('normal! ' .. idx .. 'z=') end -end - --- todo list -if pcall(require, "todo-comments") then - map("n", "<leader>td", "<cmd>TodoQuickFix<CR>", { desc = 'open up list of TODO\'s' }) -end - --- harpoon -if (pcall(require, 'harpoon')) then - local harpoon = require("harpoon") - - map("n", "<leader>a", function() - harpoon:list():append() - vim.notify('added new file to quickmarks', vim.log.levels.INFO, { - title = misc.appid, - }) - end) - map('n', '<C-q>', function() harpoon:list():select(1) end) - map('n', '<C-g>', function() harpoon:list():select(2) end) - map('n', '<C-h>', function() harpoon:list():select(3) end) - map('n', '<C-i>', function() harpoon:list():select(4) end) - - map("n", "<C-S-P>", function() harpoon:list():prev() end) - map("n", "<C-S-N>", function() harpoon:list():next() end) - - map("n", "<C-e>", function() require("core.harpoon").switcher() end) -end - -map('n', '<leader>u', '<cmd>UndotreeToggle<CR>', { desc = 'Open undo tree.' }) -map('n', '<leader>f', '<cmd>SFMToggle<CR>', { desc = 'Open file tree view.' }) -map('n', '<C-j>', '<cmd>JABSOpen<CR>', { desc = 'Switch between buffers.' }) - -if pcall(require, "smart-splits") then - local smartsplits = require('smart-splits') -- resizing buffers (toggleable) - map('n', '<leader>r', smartsplits.start_resize_mode) -end - --- neogen -if pcall(require, "neogen") then - map('n', '<leader>df', require("neogen").generate, { - desc = 'Generate anotations', - }) -end +end) --- venn -function _G.Toggle_venn() - local mapb = vim.api.nvim_buf_set_keymap - local venn_enabled = vim.inspect(vim.b.venn_enabled) - if venn_enabled == "nil" then - vim.notify("Enabled venn mode", vim.log.levels.LOW, { title = misc.appid }) - vim.b.venn_enabled = true - vim.cmd([[setlocal ve=all]]) - -- draw a line on HJKL keystokes - mapb(0, "n", "J", "<C-v>j:VBox<CR>", { noremap = true }) - mapb(0, "n", "K", "<C-v>k:VBox<CR>", { noremap = true }) - mapb(0, "n", "L", "<C-v>l:VBox<CR>", { noremap = true }) - mapb(0, "n", "H", "<C-v>h:VBox<CR>", { noremap = true }) - -- draw a box by pressing "f" with visual selection - mapb(0, "v", "f", ":VBox<CR>", { noremap = true }) - else - vim.notify("Disabled venn mode", vim.log.levels.LOW, { title = misc.appid }) - vim.cmd[[setlocal ve=]] - vim.cmd[[mapclear <buffer>]] - vim.b.venn_enabled = nil +local spellsuggest_select = function() + if vim.v.count > 0 then + spell_on_choice(nil, vim.v.count) + return end + local cword = vim.fn.expand('<cword>') + local prompt = 'Change ' .. vim.inspect(cword) .. ' to:' + vim.ui.select(vim.fn.spellsuggest(cword, vim.o.lines), { prompt = prompt }, spell_on_choice) end --- toggle keymappings for venn using <leader>v -map('n', '<leader>v', ":lua Toggle_venn()<CR>") + +vim.keymap.set('n', 'z=', spellsuggest_select, { desc = 'Shows spelling suggestions' }) diff --git a/lua/core/context.lua b/lua/conf/context.lua index 63463cd..b685afe 100644 --- a/lua/core/context.lua +++ b/lua/conf/context.lua @@ -7,6 +7,7 @@ vim.cmd([[:amenu PopUp.Save\ All\ Buffers <cmd>:wa<CR>]]) vim.cmd([[:nmenu PopUp.Select\ All ggVG]]) vim.cmd([[:nmenu PopUp.Undo u]]) vim.cmd([[:nmenu PopUp.Redo <C-r>]]) +vim.cmd([[:nmenu PopUp.Inspect <cmd>Inspect<CR>]]) vim.cmd([[:amenu PopUp.-1- <nop>]]) -- dividers vim.cmd([[:nmenu PopUp.Copy\ Line yy]]) vim.cmd([[:vmenu PopUp.Copy\ Selection y]]) diff --git a/lua/conf/init.lua b/lua/conf/init.lua deleted file mode 100644 index 2029141..0000000 --- a/lua/conf/init.lua +++ /dev/null @@ -1,4 +0,0 @@ -misc.include('conf.plugins') -- load plugins first to allow colorscheme to be set in opts -misc.include('conf.opts') -misc.include('conf.binds') -misc.include('conf.auto') diff --git a/lua/conf/opts.lua b/lua/conf/opts.lua index 0d0863c..91c8055 100644 --- a/lua/conf/opts.lua +++ b/lua/conf/opts.lua @@ -1,65 +1,50 @@ --- better ui ------------------------------------------------------------------ -if pcall(require, "notify") then vim.notify = require("notify") end -o.colorcolumn = { 80 } +-- color stuff +if vim.fn.has("termguicolors") then + vim.opt.termguicolors = true +end -- buffer -o.scrolloff = 5 -o.wrap = true -- wraping lines -o.linebreak = true -- fix where line is wraped -o.cursorline = true - --- statusbar -o.laststatus = 3 -o.cmdheight = 1 -o.showmode = false -- stop vim from showing mode (we have a statusbar) - --- tabline -o.showtabline = 2 +vim.opt.scrolloff = 5 +vim.opt.wrap = true -- wraping lines +vim.opt.linebreak = true -- fix where line is wraped +vim.opt.cursorline = true -- indents + tabs local tabwidth = 2 -o.expandtab = true -o.smarttab = true -o.cindent = true -o.autoindent = true -o.tabstop = tabwidth -o.shiftwidth = tabwidth -o.softtabstop = tabwidth - --- colorscheme -if vim.fn.has("termguicolors") then - o.termguicolors = true -end -misc.colorscheme('mellow') - --- better editing ------------------------------------------------------------- -o.clipboard = 'unnamedplus' -- system clipboard -o.splitkeep = "screen" -- keep same text on screen when spliting -o.updatetime = 200 - --- file saving ---------------------------------------------------------------- -o.swapfile = false -o.undofile = true -o.confirm = true - --- searching ------------------------------------------------------------------ -o.ignorecase = true -o.smartcase = true -o.wrapscan = true -o.showmatch = true -o.incsearch = true - --- wild menus ----------------------------------------------------------------- -o.wildoptions = 'pum' -o.pumblend = 3 -o.pumheight = 20 - -o.wildignorecase = true -o.wildignore = '*.o' - --- netrw ---------------------------------------------------------------------- -g.netrw_banner = 1 -g.netrw_localcopydircmd = 'cp -r' -g.netrw_winsize = 30 -g.netrw_liststyle = 1 -g.netrw_preview = 1 +vim.opt.expandtab = true +vim.opt.smarttab = true +vim.opt.cindent = true +vim.opt.autoindent = true +vim.opt.tabstop = tabwidth +vim.opt.shiftwidth = tabwidth +vim.opt.softtabstop = tabwidth + +vim.opt.clipboard = 'unnamedplus' -- system clipboard +vim.opt.updatetime = 200 + +-- file saving +vim.opt.swapfile = false +vim.opt.undofile = true +vim.opt.confirm = true + +-- searching +vim.opt.ignorecase = true +vim.opt.smartcase = true +vim.opt.wrapscan = true +vim.opt.showmatch = true +vim.opt.incsearch = true + +-- wild menus +vim.opt.wildoptions = 'pum' +vim.opt.pumblend = 3 +vim.opt.pumheight = 20 + +vim.opt.wildignorecase = true +vim.opt.wildignore = '*.o' + +-- netrw +vim.g.netrw_banner = 0 +vim.g.netrw_winsize = 30 +vim.g.netrw_liststyle = 1 +vim.g.netrw_sizestyle = "H" +vim.g.netrw_hide = 1 diff --git a/lua/conf/plugins.lua b/lua/conf/plugins.lua deleted file mode 100644 index 366b02f..0000000 --- a/lua/conf/plugins.lua +++ /dev/null @@ -1,167 +0,0 @@ -require('dep') { - -- dep manages dep ---------------------------------------------------------- - { 'squibid/dep', - url = 'https://git.squi.bid/dep', - pin = true, - -- branch = 'dev' - }, - - -- colorschemes ------------------------------------------------------------- - { 'mellow-theme/mellow.nvim', - requires = 'nvim-treesitter/nvim-treesitter' - }, - - -- ui ----------------------------------------------------------------------- - { 'lukas-reineke/indent-blankline.nvim' }, -- indentation indicators - { 'folke/which-key.nvim' }, -- key map help - { 'rcarriga/nvim-notify' }, -- notifications - { 'tjdevries/express_line.nvim', -- status bar - requires = 'nvim-lua/plenary.nvim' - }, - { 'goolord/alpha-nvim' }, -- start page - { 'dinhhuy258/sfm.nvim', -- tree view - deps = 'dinhhuy258/sfm-git.nvim' - }, - { 'matbme/JABS.nvim' }, -- buffer switcher - { 'stevearc/dressing.nvim', -- nice ui selectors - requires = 'nvim-telescope/telescope.nvim' - }, - { 'lukas-reineke/headlines.nvim', - requires = 'nvim-neorg/neorg' - }, - { 'squibid/tar', -- tab bar - url = 'https://git.squi.bid/tar' - }, - - -- functional plugins ------------------------------------------------------- - { 'lewis6991/gitsigns.nvim' }, -- very helpful git things - { 'chentoast/marks.nvim' }, -- marks in gutter - { 'vidocqh/auto-indent.nvim' }, -- better tabbing into indents - { 'mbbill/undotree' }, -- careful this one is written in vimscript - { 'dhruvasagar/vim-table-mode' }, -- same with this one - { 'altermo/ultimate-autopair.nvim', -- autopairs - branch = 'v0.6' - }, - { 'numToStr/Comment.nvim' }, - { 'ahmedkhalf/project.nvim' }, -- cd into root of project - { 'mrjones2014/smart-splits.nvim'}, -- buffer resizing - { 'ThePrimeagen/harpoon', -- super duper fast navigation through files - branch = 'harpoon2', - requires = 'nvim-lua/plenary.nvim' - }, - - -- note taking -------------------------------------------------------------- - { 'nvim-neorg/neorg', - branch = '*', - requires = { - 'nvim-lua/plenary.nvim', - 'nvim-treesitter/nvim-treesitter', - 'folke/zen-mode.nvim', - { 'vhyrro/luarocks.nvim', - config = function() - -- NOTE: you need the lua.h header file for lua version 5.1 and - -- luarocks on void linux run: xbps-install luarocks lua51-devel - - local output = "" - local function cbstd(_, data, _) - data = table.concat(data) - data = data:gsub("\r", "\n") - output = output..data - end - -- actually start the build here - vim.fn.jobstart({ "nvim", "-l", "build.lua" }, { - on_stdout = cbstd, - on_stderr = cbstd, - on_exit = function() - -- return build status as a notification - vim.notify(output, vim.log.levels.INFO, { title = misc.appid }) - end - }) - end - } - }, - deps = { 'nvim-neorg/neorg-telescope', - requires = 'nvim-telescope/telescope.nvim' - } - }, - - { 'jbyuki/venn.nvim' }, - - -- fzf ---------------------------------------------------------------------- - { 'nvim-telescope/telescope.nvim', - requires = 'nvim-lua/plenary.nvim', - deps = { - 'nvim-telescope/telescope-file-browser.nvim', - 'nvim-telescope/telescope-symbols.nvim', - 'axieax/urlview.nvim' - } - }, - { 'nvim-telescope/telescope-fzf-native.nvim', - config = function() - vim.cmd('make') - end, - requires = 'nvim-telescope/telescope.nvim' - }, - - -- treesitter + colorizing -------------------------------------------------- - { 'nvim-treesitter/nvim-treesitter', - deps = { - 'Wansmer/treesj', - 'nvim-treesitter/nvim-treesitter-context' - } - }, - { 'NvChad/nvim-colorizer.lua' }, - { 'folke/todo-comments.nvim', - requires = 'nvim-lua/plenary.nvim' - }, - - -- cmp ---------------------------------------------------------------------- - { 'hrsh7th/nvim-cmp', - deps = { - 'lukas-reineke/cmp-under-comparator', -- better results - 'hrsh7th/cmp-buffer', -- buffers - 'FelipeLema/cmp-async-path', -- path - 'hrsh7th/cmp-nvim-lsp', -- lsp - 'hrsh7th/cmp-nvim-lua', -- nvim lua api - 'hrsh7th/cmp-nvim-lsp-signature-help', -- completion information - { 'L3MON4D3/cmp-luasnip-choice', -- luasnip - requires = 'L3MON4D3/LuaSnip' - } - }, - }, - - -- snippets ----------------------------------------------------------------- - { 'L3MON4D3/LuaSnip', - deps = 'rafamadriz/friendly-snippets', - config = function() - vim.cmd('make install_jsregexp') - end - }, - - -- lsp ---------------------------------------------------------------------- - { 'neovim/nvim-lspconfig' }, -- setup lsp - { 'j-hui/fidget.nvim', -- shows lsp progress - branch = 'legacy' - }, - - { 'dnlhc/glance.nvim' }, -- diagnostic info at a glance - { 'aznhe21/actions-preview.nvim', -- codeactions - requires = 'nvim-telescope/telescope.nvim' - }, - - { 'danymat/neogen', -- generate lsp annotations - requires = 'nvim-treesitter/nvim-treesitter' - }, - - { 'whynothugo/lsp_lines.nvim', - url = 'https://git.sr.ht/~whynothugo/lsp_lines.nvim' - }, - - -- mason -------------------------------------------------------------------- - { 'williamboman/mason.nvim', - deps = { - 'WhoIsSethDaniel/mason-tool-installer.nvim', - 'williamboman/mason-lspconfig.nvim' - } - } -} diff --git a/lua/conf/plugins/biscuit.lua b/lua/conf/plugins/biscuit.lua new file mode 100644 index 0000000..d5a1067 --- /dev/null +++ b/lua/conf/plugins/biscuit.lua @@ -0,0 +1 @@ +return { 'Biscuit-Theme/nvim' } diff --git a/lua/conf/plugins/cmp.lua b/lua/conf/plugins/cmp.lua new file mode 100644 index 0000000..5dbb6ed --- /dev/null +++ b/lua/conf/plugins/cmp.lua @@ -0,0 +1,170 @@ +local function has_words_before() + unpack = unpack or table.unpack + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true) + [1]:sub(col, col):match("%s") == nil +end + +return { 'hrsh7th/nvim-cmp', + requires = { + 'danymat/neogen', + 'nvim-treesitter/nvim-treesitter', + 'lukas-reineke/cmp-under-comparator' -- better results + }, + + -- suppliers for completions (they require nvim-cmp to be loaded before they are) + deps = { + 'hrsh7th/cmp-buffer', -- buffers + 'FelipeLema/cmp-async-path', -- path + 'hrsh7th/cmp-nvim-lsp', -- lsp + 'hrsh7th/cmp-nvim-lsp-signature-help', -- completion information + { 'L3MON4D3/cmp-luasnip-choice', -- luasnip + requires = 'L3MON4D3/LuaSnip' + } + }, + + function() + local cmp = require('cmp') + local luasnip = require('luasnip') + local neogen = require('neogen') + + cmp.setup { + -- disable when in comments + enabled = function() + local context = require('cmp.config.context') + if vim.api.nvim_get_mode().mode == 'c' then + return true + else + return not context.in_treesitter_capture("comment") + and not context.in_syntax_group("Comment") + end + end, + + -- completion sources + sources = cmp.config.sources { + { name = 'nvim_lsp', priority = 999 }, + { name = 'luasnip_choice', priority = 750 }, + { name = 'buffer', max_item_count = 3 }, + { name = 'async_path', max_item_count = 5 }, + { name = 'neorg' }, + { name = 'nvim_lsp_signature_help' } + }, + + -- how to sort results + sorting = { + comparators = { + cmp.config.compare.offset, + cmp.config.compare.exact, + cmp.config.compare.score, + require('cmp-under-comparator').under, + cmp.config.compare.kind, + cmp.config.compare.sort_text, + cmp.config.compare.length, + cmp.config.compare.order, + } + }, + + -- appearance of window + window = { + completion = { + scrollbar = false, + border = 'solid', + winhighlight = "Normal:WinBarNC,FloatBorder:WinBarNC,Search:WinBarNC", + }, + documentation = { + border = 'solid', + winhighlight = "Normal:WinBarNC,FloatBorder:WinBarNC,Search:WinBarNC", + } + }, + + -- position of window + view = { + entries = { + name = 'custom', + selection_order = 'near_cursor' + } + }, + + -- formatting of content + formatting = { + fields = { 'menu', 'abbr', 'kind' }, + format = function(entry, item) + local menu_icon = { + nvim_lsp = 'λ', + nvim_lua = 'v', + calc = '+', + luasnip = '%', + buffer = '@', + path = '#' + } + + item.menu = menu_icon[entry.source.name] + return item + end + }, + + experimental = { + ghost_text = true + }, + + -- snippet integration + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end + }, + + -- mappings + mapping = cmp.mapping.preset.insert { + ["<Tab>"] = cmp.mapping(function(fallback) + if #cmp.get_entries() == 1 then + cmp.confirm({ select = true }) + elseif cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_locally_jumpable() then + luasnip.expand_or_jump() + elseif has_words_before() then + cmp.complete() + if #cmp.get_entries() == 1 then + cmp.confirm({ select = true }) + end + elseif neogen.jumpable() then + neogen.jump_next() + else + fallback() + end + end, { "i", "s" }), + + ["<S-Tab>"] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + elseif neogen.jumpable(-1) then + neogen.jump_prev() + else + fallback() + end + end, { "i", "s" }), + + ['<CR>'] = cmp.mapping { + i = function(fallback) + if cmp.visible() and cmp.get_active_entry() then + cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false }) + else + fallback() + end + end, + s = cmp.mapping.confirm({ select = true }), + c = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, + select = true }), + }, + + ["<C-u>"] = cmp.mapping.scroll_docs(-4), + ["<C-d>"] = cmp.mapping.scroll_docs(4), + ['<ESC>'] = cmp.mapping.close(), + ["<C-e>"] = cmp.mapping.abort() + } + } + end +} diff --git a/lua/conf/plugins/comment.lua b/lua/conf/plugins/comment.lua new file mode 100644 index 0000000..9a6373d --- /dev/null +++ b/lua/conf/plugins/comment.lua @@ -0,0 +1,7 @@ +return { 'numToStr/Comment.nvim', + function() + require('Comment').setup { + ignore = '^$' + } + end +} diff --git a/lua/conf/plugins/dressing.lua b/lua/conf/plugins/dressing.lua new file mode 100644 index 0000000..64f9723 --- /dev/null +++ b/lua/conf/plugins/dressing.lua @@ -0,0 +1,21 @@ +local branch = nil +if vim.version().minor == 7 then + branch = 'nvim-0.7' +elseif vim.version().minor == 5 then + branch = 'nvim-0.5' +end + +return { 'stevearc/dressing.nvim', + disable = vim.version().minor < 5, + branch = branch, + requires = 'nvim-telescope/telescope.nvim', + function() + require('dressing').setup { + input = { + title_pos = "center", + border = 'solid', + relative = "win" + } + } + end +} diff --git a/lua/conf/plugins/fidget.lua b/lua/conf/plugins/fidget.lua new file mode 100644 index 0000000..e36488e --- /dev/null +++ b/lua/conf/plugins/fidget.lua @@ -0,0 +1,34 @@ +return { 'j-hui/fidget.nvim', + disable = vim.version().minor < 9, + function() + local notification_defaults = require("fidget.notification").default_config + notification_defaults["icon"] = "" + + require('fidget').setup { + progress = { + display = { + progress_icon = { + pattern = "line", + period = 1 + }, + done_icon = ":)", + } + }, + notification = { + override_vim_notify = true, + configs = { + default = notification_defaults, + }, + view = { + icon_separator = " ", + group_separator = "---", + group_separator_hl = "Comment", + }, + window = { + zindex = 44, + relative = "win" + } + } + } + end +} diff --git a/lua/conf/plugins/gitsigns.lua b/lua/conf/plugins/gitsigns.lua new file mode 100644 index 0000000..f168b93 --- /dev/null +++ b/lua/conf/plugins/gitsigns.lua @@ -0,0 +1,78 @@ +local misc = require('core.misc') +local map = misc.map + +return { 'lewis6991/gitsigns.nvim', + disable = vim.version().minor < 9, + function() + local gs = require("gitsigns") + + gs.setup { + signs = { + add = { text = '│' }, + change = { text = '│' }, + delete = { text = '-' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + untracked = { text = '┆' } + }, + + signcolumn = true, + numhl = false, + linehl = false, + word_diff = false, + + watch_gitdir = { + interval = 1000, + follow_files = true + }, + + attach_to_untracked = true, + current_line_blame_formatter = '<author>, <author_time:%Y-%m-%d> - <summary>', + + preview_config = { border = 'solid' }, + + on_attach = function(bufnr) + local opts = { buffer = bufnr } + + -- Navigation + map('n', ']c', function() + if vim.wo.diff then + return ']c' + end + vim.schedule(function() gs.next_hunk() end) + return '<Ignore>' + end, { expr = true, buffer = bufnr }) + + map('n', '[c', function() + if vim.wo.diff then + return '[c' + end + vim.schedule(function() gs.prev_hunk() end) + return '<Ignore>' + end, { expr = true, buffer = bufnr }) + + -- Actions + map('n', '<leader>hs', gs.stage_hunk, opts) + map('n', '<leader>hr', gs.reset_hunk, opts) + map('v', '<leader>hs', function() + gs.stage_hunk { vim.fn.line('.'), vim.fn.line('v') } + end, opts) + map('v', '<leader>hr', function() + gs.reset_hunk { vim.fn.line('.'), vim.fn.line('v') } + end, opts) + map('n', '<leader>hS', gs.stage_buffer, opts) + map('n', '<leader>hu', gs.undo_stage_hunk, opts) + map('n', '<leader>hR', gs.reset_buffer, opts) + map('n', '<leader>hp', gs.preview_hunk, opts) + map('n', '<leader>hb', function() gs.blame_line { full=true } end, opts) + map('n', '<leader>tb', gs.toggle_current_line_blame, opts) + map('n', '<leader>hd', gs.diffthis, opts) + map('n', '<leader>hD', function() gs.diffthis('~') end, opts) + map('n', '<leader>td', gs.toggle_deleted, opts) + + -- Text object + map({ 'o', 'x' }, 'ih', ':<C-U>Gitsigns select_hunk<CR>', opts) + end + } + end +} diff --git a/lua/conf/plugins/glance.lua b/lua/conf/plugins/glance.lua new file mode 100644 index 0000000..c5a4d41 --- /dev/null +++ b/lua/conf/plugins/glance.lua @@ -0,0 +1,44 @@ +local misc = require('core.misc') +local map = misc.map + +return { 'dnlhc/glance.nvim', + disable = vim.version().minor < 7, + function() + require('glance').setup { + border = { + enable = true, + top_char = '', + bottom_char = '─', + }, + folds = { + fold_closed = '+', + fold_open = '-', + folded = true + }, + theme = { + enable = false + }, + hooks = { + before_open = function(results, open, jump, method) + local uri = vim.uri_from_bufnr(0) + if #results == 1 then + local target_uri = results[1].uri or results[1].targetUri + + if target_uri == uri then + jump() + misc.timeout_highlight() + return + end + end + + open() + end + } + } + + map('n', 'gd', '<cmd>Glance definitions<CR>') + map('n', 'gr', '<cmd>Glance references<CR>') + map('n', 'gy', '<cmd>Glance type_definitions<CR>') + map('n', 'gi', '<cmd>Glance implementations<CR>') + end +} diff --git a/lua/conf/plugins/harpoon.lua b/lua/conf/plugins/harpoon.lua new file mode 100644 index 0000000..cb2edca --- /dev/null +++ b/lua/conf/plugins/harpoon.lua @@ -0,0 +1,31 @@ +local misc = require('core.misc') +local map = misc.map + +return { 'ThePrimeagen/harpoon', + disable = vim.version().minor < 8, + branch = 'harpoon2', + requires = 'nvim-lua/plenary.nvim', + function() + local harpoon = require("harpoon") + + harpoon:setup() + + map("n", "<leader>a", function() + harpoon:list():add() + vim.notify("added "..vim.fn.expand("%:t").." to quickmarks", vim.log.levels.INFO, { + title = misc.appid, + }) + end, { desc = "add current file to quickmarks" }) + + map("n", "<C-e>", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end) + + map("n", "<C-h>", function() harpoon:list():select(1) end) + map("n", "<C-t>", function() harpoon:list():select(2) end) + map("n", "<C-n>", function() harpoon:list():select(3) end) + map("n", "<C-s>", function() harpoon:list():select(4) end) + + -- Toggle previous & next buffers stored within Harpoon list + map("n", "<C-S-P>", function() harpoon:list():prev() end) + map("n", "<C-S-N>", function() harpoon:list():next() end) + end +} diff --git a/lua/conf/plugins/headlines.lua b/lua/conf/plugins/headlines.lua new file mode 100644 index 0000000..c932d72 --- /dev/null +++ b/lua/conf/plugins/headlines.lua @@ -0,0 +1,28 @@ +return { 'lukas-reineke/headlines.nvim', + requires = 'nvim-treesitter/nvim-treesitter', + function() + require('headlines').setup { + norg = { + headline_highlights = { + "@neorg.headings.1.title", + "@neorg.headings.2.title", + "@neorg.headings.3.title", + "@neorg.headings.4.title", + "@neorg.headings.5.title", + "@neorg.headings.6.title" + }, + bullets = { "", "", "", "" }, + }, + markdown = { + headline_highlights = { + "@neorg.headings.1.title", + "@neorg.headings.2.title", + "@neorg.headings.3.title", + "@neorg.headings.4.title", + "@neorg.headings.5.title", + "@neorg.headings.6.title" + } + } + } + end +} diff --git a/lua/conf/plugins/incline.lua b/lua/conf/plugins/incline.lua new file mode 100644 index 0000000..03b4284 --- /dev/null +++ b/lua/conf/plugins/incline.lua @@ -0,0 +1,12 @@ +return { 'b0o/incline.nvim', + function() + vim.cmd('set laststatus=3') + + require('incline').setup { + hide = { + focused_win = true, + cursorline = true + } + } + end +} diff --git a/lua/conf/plugins/jdtls.lua b/lua/conf/plugins/jdtls.lua new file mode 100644 index 0000000..e9808d6 --- /dev/null +++ b/lua/conf/plugins/jdtls.lua @@ -0,0 +1,3 @@ +return { 'mfussenegger/nvim-jdtls', + disable = vim.version().minor < 6 +} diff --git a/lua/conf/plugins/lsp_lines.lua b/lua/conf/plugins/lsp_lines.lua new file mode 100644 index 0000000..b257de5 --- /dev/null +++ b/lua/conf/plugins/lsp_lines.lua @@ -0,0 +1,14 @@ +return { 'whynothugo/lsp_lines.nvim', + url = 'https://git.sr.ht/~whynothugo/lsp_lines.nvim', + requires = 'neovim/nvim-lspconfig', + function() + require('lsp_lines').setup() + + vim.diagnostic.config { + virtual_lines = { + highlight_whole_line = false, + only_current_line = true + } + } + end +} diff --git a/lua/conf/plugins/lspconfig.lua b/lua/conf/plugins/lspconfig.lua new file mode 100644 index 0000000..3dce638 --- /dev/null +++ b/lua/conf/plugins/lspconfig.lua @@ -0,0 +1,18 @@ +return { 'neovim/nvim-lspconfig', + disable = vim.version().minor < 8, + function() + vim.diagnostic.config { + virtual_text = false, + signs = true, + update_in_insert = false, + underline = true, + severity_sort = true + } + + vim.lsp.handlers['textDocument/hover'] = vim.lsp.with( + vim.lsp.handlers.hover, { border = 'solid' }) + + vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with( + vim.lsp.handlers.signature_help, { border = 'solid' }) + end +} diff --git a/lua/conf/plugins/luasnip.lua b/lua/conf/plugins/luasnip.lua new file mode 100644 index 0000000..26b293b --- /dev/null +++ b/lua/conf/plugins/luasnip.lua @@ -0,0 +1,52 @@ +local misc = require('core.misc') +local map = misc.map + +return { 'L3MON4D3/LuaSnip', + branch = 'v2.3.0', + disable = vim.version().minor < 7, + config = function() + vim.cmd('make install_jsregexp') + end, + function() + local luasnip = require('luasnip') + local types = require("luasnip.util.types") + + luasnip.config.set_config { + history = true, -- return back into snippet + updateevents = { "TextChanged", "TextChangedI" }, -- update on text insert + ext_opts = { + [types.choiceNode] = { + active = { + virt_text = {{ "●", "@boolean" }} + } + }, + [types.insertNode] = { + active = { + virt_text = {{ "●", "@constant" }} + } + }, + }, + } + + map({"i", "s"}, { "<C-e>", "<C-a>" }, function() + if luasnip.choice_active() then + luasnip.change_choice(1) + end + end) + + map({"i", "s"}, "<C-k>", function() + if luasnip.expandable(-1) then + luasnip.expand(-1) + end + end) + + -- load all snippets from snippet directory + for _, file in ipairs(vim.api.nvim_get_runtime_file("lua/snippets/*.lua", true)) do + local fn = file:gsub('^.*/', ''):gsub('%.lua$', '') + local ret = misc.include('snippets.'..fn) + if type(ret) ~= "boolean" then + luasnip.add_snippets(fn, ret, { key = fn }) + end + end + end +} diff --git a/lua/conf/plugins/mason-lspconfig.lua b/lua/conf/plugins/mason-lspconfig.lua new file mode 100644 index 0000000..edeaf93 --- /dev/null +++ b/lua/conf/plugins/mason-lspconfig.lua @@ -0,0 +1,369 @@ +local misc = require('core.misc') +local map, auto, augroup = misc.map, misc.auto, misc.augroup + +return { 'williamboman/mason-lspconfig.nvim', + requires = { + 'williamboman/mason.nvim', + 'mfussenegger/nvim-jdtls', + 'neovim/nvim-lspconfig' + }, + function() + local util = require('lspconfig.util') + + -- configure lsp when attached + local function lsp_attach(client, bufnr) + -- helper function(s) + local function set_lsp_sign(name, text) + vim.fn.sign_define(name, { text = text, texthl = name }) + end + + set_lsp_sign("DiagnosticSignError", "x") + set_lsp_sign("DiagnosticSignWarn" , "!") + set_lsp_sign("DiagnosticSignInfo" , "i") + set_lsp_sign("DiagnosticSignHint" , "h") + + local opts = { buffer = bufnr } + -- LSP actions + map('n', 'K', vim.lsp.buf.hover, opts) + map('n', 'gD', vim.lsp.buf.definition, opts) + -- map('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<cr>') + map('n', 'gI', vim.lsp.buf.implementation, opts) + map('n', 'gY', vim.lsp.buf.type_definition, opts) + map('n', 'gR', vim.lsp.buf.references, opts) + map('n', '<S-Tab>', vim.lsp.buf.signature_help, opts) + map('n', '<leader>lr', vim.lsp.buf.rename, opts) + map('n', '<F2>', vim.lsp.buf.rename, opts) + map('n', 'gA', vim.lsp.buf.code_action, { + buffer = bufnr, + desc = 'check code actions', + }) + map('n', '<F4>', vim.lsp.buf.code_action, { + buffer = bufnr, + desc = 'check code actions' + }) + + -- Diagnostics + map('n', '[d', vim.diagnostic.goto_prev) + map('n', ']d', vim.diagnostic.goto_next) + end + + -- setup lsp capabilities + local capabilities = vim.lsp.protocol.make_client_capabilities() + capabilities.textDocument.completion.completionItem = { + documentationFormat = { "markdown", "plaintext" }, + snippetSupport = true, + preselectSupport = true, + insertReplaceSupport = true, + labelDetailsSupport = true, + deprecatedSupport = true, + commitCharactersSupport = true, + tagSupport = { + valueSet = { 1 } + }, + resolveSupport = { + properties = { + "documentation", + "detail", + "additionalTextEdits" + } + } + } + + -- setup language servers + require('mason-lspconfig').setup { + ensure_installed = { + "lua_ls", + "clangd", + "jdtls", + "tsserver", + "phpactor", + "html", + "cssls", + "bashls", + "zls" + -- "asm-lsp", -- seems to be broken + } + } + require('mason-lspconfig').setup_handlers { + function(server_name) + require('lspconfig')[server_name].setup { + on_attach = lsp_attach, + capabilities = capabilities + } + end, + + -- setup luals + ["lua_ls"] = function(server_name) + local root_files = { '.luarc.json', '.luarc.jsonc', '.luacheckrc', + '.stylua.toml', 'stylua.toml', 'selene.toml', 'selene.yml', + 'README.md' + } + + -- FIXME: for some reason luals randomly resets the indentation of code + -- when pressing o or O. Right now this is a minor annoyance I will deal + -- with in exchange for really good lua lsp support. + -- + -- FIXME: luals also seems to start up twice and sends back twice the + -- completions (one configured with the below settings and one without) + require('lspconfig')[server_name].setup { + on_attach = lsp_attach, + settings = { + Lua = { + diagnostics = { + globals = { "vim", 'mp' } + }, + runtime = { + version = 'LuaJIT' + }, + format = { + enable = false + }, + workspace = { + checkThirdParty = false, + library = { + vim.env.VIMRUNTIME + } + } + } + }, + + root_dir = function(fname) + local root = util.root_pattern(unpack(root_files))(fname) + if root and root ~= vim.env.HOME then + return root + end + + root = util.root_pattern('lua/')(fname) + if root then + return root + end + return util.find_git_ancestor(fname) + end + } + end, + + -- setup clangd + ["clangd"] = function(server_name) + require('lspconfig')[server_name].setup { + on_attach = function(client, bufnr) + lsp_attach(client, bufnr) + + -- add some clangd specific mappings + local opts = { buffer = bufnr } + map("n", "<leader>o", "<cmd>ClangdSwitchSourceHeader<CR>", opts) + end, + capabilities = capabilities, + + cmd = { + "clangd", + "--background-index", + "--clang-tidy", + "--header-insertion=iwyu", + "--completion-style=detailed", + "--function-arg-placeholders", + "--fallback-style=llvm" + }, + init_options = { + usePlaceholders = true, + clangdFileStatus = true, + fallback_flags = { + "-xc" -- makes clangd think we're using c instead of c++ + } + } + } + end, + + -- setup jdtls + ["jdtls"] = function(server_name) + auto("Filetype", { + pattern = "java", + callback = function() + -- must be a java interpreter of version 17 or greater + local java = "java" + + local buffer = {} + ---@type function + local startlsp + + -- check if version of java in use is high enough + vim.fn.jobstart({ java, vim.fn.stdpath('config').."/extras/JavaVersion.java" }, { + stdin = nil, + on_stdout = function(_, data, _) + table.insert(buffer, table.concat(data)) + end, + on_exit = function(_, exit_code, _) + local v = vim.version.parse(table.concat(buffer)) + + -- if there's an error, no version info, or the java version is + -- less than 17 stop the lsp from starting + if exit_code ~= 0 then + vim.notify(string.format( + "java version check failed: exit code %s", exit_code), + vim.log.levels.ERROR, { title = misc.appid }) + return + elseif not v then + vim.notify("no java version info found", vim.log.levels.ERROR, + { title = misc.appid }) + return + elseif v.major < 17 then + vim.notify(string.format( + "java version %s < 17.0.0 Cannot run jdtls, bailing out", + v[1].."."..v[2].."."..v[3]), + vim.log.levels.ERROR, { title = misc.appid }) + return + end + + startlsp() + end + }) + + function startlsp() + local ok, jdtls = pcall(require, "jdtls") + if not ok then + vim.notify("jdtls not found, can't start java lsp", + vim.log.levels.ERROR, {}) + return + end + + local config = {} + + config.on_attach = function(client, bufnr) + lsp_attach(client, bufnr) + + -- add some jdtls specific mappings + local opts = { buffer = bufnr } + map('n', 'cri', jdtls.organize_imports, opts) + map('n', 'crv', jdtls.extract_variable, opts) + map('n', 'crc', jdtls.extract_constant, opts) + map('x', 'crv', "<esc><cmd>lua require('jdtls').extract_variable(true)<cr>", opts) + map('x', 'crc', "<esc><cmd>lua require('jdtls').extract_constant(true)<cr>", opts) + map('x', 'crm', "<esc><Cmd>lua require('jdtls').extract_method(true)<cr>", opts) + + -- refresh the codelens every time after writing the file + local jdtls_cmds = augroup("jdtls_cmds") + + pcall(vim.lsp.codelens.refresh) + auto('BufWritePost', { + buffer = bufnr, + group = jdtls_cmds, + desc = 'refresh codelens', + callback = function() + pcall(vim.lsp.codelens.refresh) + end + }) + end + + -- setup path stuff + local path = {} + local jdtls_install = require('mason-registry').get_package('jdtls'):get_install_path() + path.data_dir = vim.fn.stdpath('cache')..'/nvim-jdtls' + path.java_agent = jdtls_install..'/lombok.jar' + path.launcher_jar = vim.fn.glob(jdtls_install..'/plugins/org.eclipse.equinox.launcher_*.jar') + path.platform_config = jdtls_install..'/config_linux' + path.bundles = {} + + -- data dir + local data_dir = path.data_dir..'/'..vim.fn.fnamemodify(vim.fn.getcwd(), ':p:h:t') + + -- enable basic capabilities + config.capabilities = capabilities + + -- enable some extended client capabilities + local extendedClientCapabilities = jdtls.extendedClientCapabilities + extendedClientCapabilities.resolveAdditionalTextEditsSupport = true + + -- command to start the lsp server + config.cmd = { + java, -- this has to be java17 or newer + '-Declipse.application=org.eclipse.jdt.ls.core.id1', + '-Dosgi.bundles.defaultStartLevel=4', + '-Declipse.product=org.eclipse.jdt.ls.core.product', + '-Dlog.protocol=true', + '-Dlog.level=ALL', + '-Xmx1G', + '--add-modules=ALL-SYSTEM', + '--add-opens', 'java.base/java.util=ALL-UNNAMED', + '--add-opens', 'java.base/java.lang=ALL-UNNAMED', + '-jar', path.launcher_jar, + '-configuration', path.platform_config, + '-data', data_dir + } + + -- settings + config.settings = { + java = { + eclipse = { downloadSources = true }, + gradle = { enabled = true }, + maven = { downloadSources = true }, + implementationsCodeLens = { enabled = true }, + referencesCodeLens = { enabled = true }, + references = { includeDecompiledSources = true }, + symbols = { includeSourceMethodDeclarations = true }, + inlayHints = { + parameterNames = { + enabled = "all" + } + }, + completion = { + favoriteStaticMembers = { + "org.hamcrest.MatcherAssert.assertThat", + "org.hamcrest.Matchers.*", + "org.hamcrest.CoreMatchers.*", + "org.junit.jupiter.api.Assertions.*", + "java.util.Objects.requireNonNull", + "java.util.Objects.requireNonNullElse", + "org.mockito.Mockito.*" + }, + filteredTypes = { + "com.sun.*", + "io.micrometer.shaded.*", + "java.awt.*", + "jdk.*", + "sun.*" + }, + importOrder = { + "java", + "javax", + "com", + "org" + } + }, + sources = { + organizeImports = { + starThreshold = 9999, + staticStarThreshold = 9999 + } + }, + codeGeneration = { + toString = { + template = '${object.className}{${member.name()}=${member.value}, ${otherMembers}}' + }, + hashCodeEquals = { useJava7Objects = true }, + useBlocks = true, + } + } + } + config.signatureHelp = { enabled = true } + config.flags = { allow_incremental_sync = true } + + -- disable all messages from printing + config.handlers = { + ['language/status'] = function() end + } + + config.init_options = { + extendedClientCapabilities = extendedClientCapabilities, + } + + config.root_dir = vim.fs.root(0, { ".git", "mvnw", ".gradle", + "gradlew" }) + + -- start it up + jdtls.start_or_attach(config) + end + end + }) + end + } + end +} diff --git a/lua/conf/plugins/mason.lua b/lua/conf/plugins/mason.lua new file mode 100644 index 0000000..b3eeacf --- /dev/null +++ b/lua/conf/plugins/mason.lua @@ -0,0 +1,31 @@ +return { 'williamboman/mason.nvim', + disable = vim.version().minor < 7, + function() + local mason = require('mason') + + mason.setup { + ui = { + border = "solid", + width = 0.8, + height = 0.9, + + icons = { + package_installed = "+", + package_pending = "?", + package_uninstalled = "x" + } + }, + keymaps = { + toggle_package_expand = "<CR>", + install_package = "i", + update_package = "u", + check_package_version = "c", + update_all_packages = "U", + check_outdated_packages = "C", + uninstall_package = "r", + cancel_installation = "<C-c>", + apply_language_filter = "<C-f>" + } + } + end +} diff --git a/lua/conf/plugins/mellow.lua b/lua/conf/plugins/mellow.lua new file mode 100644 index 0000000..af805ed --- /dev/null +++ b/lua/conf/plugins/mellow.lua @@ -0,0 +1,35 @@ +return { 'mellow-theme/mellow.nvim', + requires = 'nvim-treesitter/nvim-treesitter', + function() + vim.g.mellow_variant = "dark" + local c = require("mellow.colors")[vim.g.mellow_variant] + + vim.g.mellow_highlight_overrides = { + -- stop inactive windows from having a darker bg + ["NormalNC"] = { link = "Normal" }, + + -- make floats darker + ["NormalFloat"] = { fg = c.fg, bg = c.bg_dark }, + ["FloatBorder"] = { link = "NormalFloat" }, + + -- neorg headings, looks extra good with lukas-reineke/headlines.nvim + ["@neorg.headings.1.title"] = { fg = c.yellow, bg = "#2a211c" }, + ["@neorg.headings.1.icon"] = { link = "@neorg.headings.1.title" }, + + ["@neorg.headings.2.title"] = { fg = c.blue, bg = '#201e25' }, + ["@neorg.headings.2.icon"] = { link = "@neorg.headings.2.title" }, + + ["@neorg.headings.3.title"] = { fg = c.cyan, bg = '#2b1b20' }, + ["@neorg.headings.3.icon"] = { link = "@neorg.headings.3.title" }, + + ["@neorg.headings.4.title"] = { fg = c.green, bg = '#1d201e' }, + ["@neorg.headings.4.icon"] = { link = "@neorg.headings.4.title" }, + + ["@neorg.headings.5.title"] = { fg = c.magenta, bg = '#251a21' }, + ["@neorg.headings.5.icon"] = { link = "@neorg.headings.5.title" }, + + ["@neorg.headings.6.title"] = { fg = c.white, bg = '#212126' }, + ["@neorg.headings.6.icon"] = { link = "@neorg.headings.6.title" } + } + end +} diff --git a/lua/conf/plugins/neogen.lua b/lua/conf/plugins/neogen.lua new file mode 100644 index 0000000..19c3422 --- /dev/null +++ b/lua/conf/plugins/neogen.lua @@ -0,0 +1,19 @@ +local misc = require('core.misc') +local map = misc.map + +return { 'danymat/neogen', + requires = { + 'nvim-treesitter/nvim-treesitter', + 'L3MON4D3/LuaSnip' + }, + function() + local neogen = require('neogen') + neogen.setup { + enabled = true, + input_after_comment = true, + snippet_engine = "luasnip", + } + + map('n', '<leader>d', neogen.generate) + end +} diff --git a/lua/conf/plugins/neorg.lua b/lua/conf/plugins/neorg.lua new file mode 100644 index 0000000..b67cb78 --- /dev/null +++ b/lua/conf/plugins/neorg.lua @@ -0,0 +1,135 @@ +-- WARNING: neorg does some pretty stupid stuff when it comes to the plugins it +-- wants (using luarocks), in order to get around all that bullshit I've +-- manually added it's dependencies. Because I don't want this to randomly break +-- I've also pinned neorg to the latest working version that I've messed around +-- with. +-- +-- NOTE: for my future self to update this thingy while not breaking +-- dependencies take a look at the build.lua for versioning info. Also make sure +-- to check the release notes on github for info on breaking changes. + +local workspace_cache = vim.fs.joinpath(vim.fn.stdpath("data"), "neorg-workspace-cache.lua") + +--- populate neorg workspaces from path or cache +---@param path string path to populate workspaces from +---@param cache boolean? if true will re populate the cache from the fs +---@return table workspaces +local function populate_workspaces(path, cache) + local workspaces = {} + cache = cache or false + + if vim.fn.filereadable(workspace_cache) == 1 and not cache then + local ok, ret = pcall(dofile, workspace_cache) + if ok and type(ret) == "table" then + return ret + end + end + + -- loop through all files in path if path is not empty + if vim.fn.empty(vim.fn.glob(path)) == 0 then + for n, t in vim.fs.dir(path) do + if string.sub(n, 1, 1) == "." or (t ~= "directory" and t ~= "link") then + goto continue + end + -- make sure this still works if the last charachter in the path isn't a '/' + workspaces[n] = (string.sub(path, #path, #path) == "/") and path..n or path.."/"..n + ::continue:: + end + end + + -- write data to cachefile + local f = io.open(workspace_cache, "w+") + if not f then + return workspaces + end + + f:write("return") + local ret = vim.inspect(workspaces) + if type(ret) == "string" then + f:write(ret) + else + f:write("false") + end + + f:close() + + return workspaces +end + +return { 'nvim-neorg/neorg', + disable = vim.version.lt(vim.version(), { 0, 10, 0 }), + branch = 'v9.1.1', + requires = { + 'nvim-lua/plenary.nvim', + 'nvim-treesitter/nvim-treesitter', + 'folke/zen-mode.nvim', + 'hrsh7th/nvim-cmp', + { 'nvim-neorg/neorg-telescope', + requires = 'nvim-telescope/telescope.nvim' + }, + + -- NOTE: these are usually installed by neorg via luarocks, the versions + -- were picked based on the build.lua found in the root of the neorg repo + { 'nvim-neotest/nvim-nio', + branch = 'v1.7.0' + }, + { 'nvim-neorg/lua-utils.nvim', + branch = 'v1.0.2' + }, + { 'MunifTanjim/nui.nvim', + branch = '0.3.0' + }, + { 'pysan3/pathlib.nvim', + branch = 'v2.2.2' + } + }, + + function() + local wsphome = (os.getenv("XDG_DOCUMENTS_DIR") or + (os.getenv("HOME").."/Documents")).."/notes/" + + require('neorg').setup { + load = { + -- not sure how to sort the modules so ima just put the empty ones first + ["core.defaults"] = {}, + ["core.export"] = {}, + ["core.export.markdown"] = {}, + ["core.integrations.telescope"] = {}, + ["core.summary"] = {}, + ["core.ui.calendar"] = {}, + + ["core.completion"] = { + config = { + engine = "nvim-cmp" + } + }, + ["core.concealer"] = { + config = { + folds = false + } + }, + ["core.dirman"] = { + config = { + -- a list of available workspaces are generated at runtime >:) + workspaces = populate_workspaces(wsphome) + } + }, + ["core.esupports.metagen"] = { + config = { + type = "auto" + } + }, + ["core.presenter"] = { + config = { + zen_mode = "zen-mode" + } + }, + ["core.qol.toc"] = { + config = { + close_after_use = true + } + } + } + } + end +} diff --git a/lua/conf/plugins/nvim-colorizer.lua b/lua/conf/plugins/nvim-colorizer.lua new file mode 100644 index 0000000..c37dfb1 --- /dev/null +++ b/lua/conf/plugins/nvim-colorizer.lua @@ -0,0 +1,11 @@ +return { 'NvChad/nvim-colorizer.lua', + disable = vim.version().minor < 7 and not vim.fn.has("termguicolors"), + function() + require('colorizer').setup { + user_default_options = { + names = false, + css = true + } + } + end +} diff --git a/lua/conf/plugins/project.lua b/lua/conf/plugins/project.lua new file mode 100644 index 0000000..afc5ecf --- /dev/null +++ b/lua/conf/plugins/project.lua @@ -0,0 +1,18 @@ +return { 'ahmedkhalf/project.nvim', + disable = vim.version().minor < 5, + function() + require('project_nvim').setup { + patterns = { + ".git", + "Makefile", + "_darcs", + ".hg", + ".bzr", + ".svn", + "package.json", + "index.norg", + "README.md" + } + } + end +} diff --git a/lua/conf/plugins/telescope.lua b/lua/conf/plugins/telescope.lua new file mode 100644 index 0000000..20f516d --- /dev/null +++ b/lua/conf/plugins/telescope.lua @@ -0,0 +1,78 @@ +local misc = require('core.misc') +local map = misc.map + +return { 'nvim-telescope/telescope.nvim', + disable = vim.version().minor < 9, + requires = { + 'nvim-lua/plenary.nvim', + { 'nvim-telescope/telescope-fzf-native.nvim', + config = function() + vim.cmd('make') + end + } + }, + function() + local telescope = require("telescope") + local actions = require('telescope.actions') + local action_layout = require("telescope.actions.layout") + + local function telescopew() + if vim.o.columns <= 80 then + return vim.o.columns + else + return 0.8 + end + end + + telescope.setup { + defaults = { + borderchars = { + prompt = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, + results = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, + preview = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, + }, + winblend = 0, + layout_strategy = 'horizontal', + sorting_strategy = 'descending', + scroll_strategy = 'limit', + layout_config = { + horizontal = { + width = telescopew(), + height = 20, + prompt_position = 'bottom', + anchor = 'N', + } + }, + mappings = { + i = { + ["<esc>"] = actions.close, + ['<C-j>'] = actions.move_selection_next, + ['<C-k>'] = actions.move_selection_previous, + ['<C-l>'] = actions.select_default, + ['<C-u>'] = actions.preview_scrolling_up, + ['<C-d>'] = actions.preview_scrolling_down, + ["<C-p>"] = action_layout.toggle_preview + }, + n = { + ["gg"] = actions.move_to_top, + ["G"] = actions.move_to_bottom, + } + } + } + } + + local telebuilt = require('telescope.builtin') + map('n', '<leader>f', function() + telebuilt.fd { follow = true } + end, { desc = 'Find files.' }) + map('n', '<leader>s', telebuilt.live_grep, { desc = 'Find string in project.' }) + map('n', '<leader>b', telebuilt.current_buffer_fuzzy_find, { + desc = 'Find string in current buffer.', + }) + + -- enable previewing in the default colorscheme switcher + telebuilt.colorscheme = function() + require("telescope.builtin.__internal").colorscheme { enable_preview = true } + end + end +} diff --git a/lua/conf/plugins/todo-comments.lua b/lua/conf/plugins/todo-comments.lua new file mode 100644 index 0000000..55ebd32 --- /dev/null +++ b/lua/conf/plugins/todo-comments.lua @@ -0,0 +1,42 @@ +local branch = nil +if vim.version().minor < 8 then + branch = 'neovim-pre-0.8.0' +end + +return { 'folke/todo-comments.nvim', + requires = 'nvim-lua/plenary.nvim', + branch = branch, + function() + require('todo-comments').setup { + keywords = { + FIX = { + icon = "# ", + alt = { "FIXME", "BUG" }, + }, + HACK = { + icon = "* ", + color = "warning", + }, + WARN = { + icon = "! ", + color = "warning", + alt = { "WARNING", "XXX" }, + }, + NOTE = { + icon = "i ", + color = "hint", + alt = { "INFO", "TODO" }, + }, + PERF = { + icon = "@ ", + alt = { "OPTIM", "PERFORMANCE", "OPTIMIZE" }, + }, + TEST = { + icon = "@ ", + color = "test", + alt = { "TESTING", "PASSED", "FAILED" }, + }, + }, + } + end +} diff --git a/lua/conf/plugins/treesitter-context.lua b/lua/conf/plugins/treesitter-context.lua new file mode 100644 index 0000000..3306e6b --- /dev/null +++ b/lua/conf/plugins/treesitter-context.lua @@ -0,0 +1,40 @@ +local misc = require("core.misc") +local map = misc.map + +local branch = nil +if vim.version().minor == 7 then + branch = 'compat/0.7' +end + +return { 'nvim-treesitter/nvim-treesitter-context', + disable = vim.version().minor < 7, + branch = branch, + requires = 'nvim-treesitter/nvim-treesitter', + function() + local treesitter_context = require("treesitter-context") + + treesitter_context.setup { + enable = true, + line_numbers = true, + separator = '─', + } + + -- mapping to jump to the first closest line of context in buffer + map("n", "[j", function() + local lline = vim.api.nvim_win_get_cursor(0)[1]; + local line + + -- go to the first closest line of context and center it + treesitter_context.go_to_context() + vim.api.nvim_input('zz') + + -- make sure we actually moved + line = vim.api.nvim_win_get_cursor(0)[1]; + if line == lline then + return + end + + misc.timeout_highlight() + end) + end +} diff --git a/lua/conf/plugins/treesitter.lua b/lua/conf/plugins/treesitter.lua new file mode 100644 index 0000000..c24d454 --- /dev/null +++ b/lua/conf/plugins/treesitter.lua @@ -0,0 +1,59 @@ +table.contains = function(self, string) + for _, v in pairs(self) do + if v == string then + return true + end + end + return false +end + +return { 'nvim-treesitter/nvim-treesitter', + disable = vim.version.lt(vim.version(), { 0, 9, 2 }), + config = function() + vim.cmd("TSUpdate") + end, + function() + require('nvim-treesitter.configs').setup { + -- good default parsers + ensure_installed = { "c", "lua", "vim", "vimdoc", "markdown", + "markdown_inline", "java", "bash", "css", "html", "luadoc" + }, + + -- install missing parsers + auto_install = true, + + -- indentation + indent = { + enable = true, + + disable = function(lang, buf) + -- disable indenting in php (it's more broken with than without) + return table.contains({ + "php" + }, lang) + end + }, + + -- enable highlighting + highlight = { + enable = true, + -- use vim highlighting in addition to treesitter + additional_vim_regex_highlighting = true, + + disable = function(lang, buf) + -- disable in diff files + local langs = { "diff" } + if table.contains(langs, lang) then + return true + end + + -- disable in big files + local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) + if ok and stats and stats.size > (1024 * 100 * 10) --[[1MB]] then + return true + end + end + } + } + end +} diff --git a/lua/conf/plugins/treesj.lua b/lua/conf/plugins/treesj.lua new file mode 100644 index 0000000..8ec65d4 --- /dev/null +++ b/lua/conf/plugins/treesj.lua @@ -0,0 +1,14 @@ +local misc = require('core.misc') +local map = misc.map + +return { 'Wansmer/treesj', + disable = vim.version().minor < 9, + requires = 'nvim-treesitter/nvim-treesitter', + function() + require('treesj').setup { + use_default_keymaps = false, + } + + map('n', '<leader>j', require('treesj').toggle, { desc = 'fold code' }) + end +} diff --git a/lua/conf/plugins/undotree.lua b/lua/conf/plugins/undotree.lua new file mode 100644 index 0000000..e649d57 --- /dev/null +++ b/lua/conf/plugins/undotree.lua @@ -0,0 +1,12 @@ +local misc = require('core.misc') +local map = misc.map + +return { 'mbbill/undotree', + function() + if (vim.g.loaded_undotree) then + vim.g.undotree_DiffAutoOpen = 0 + end + + map("n", "<leader>u", "<cmd>UndotreeToggle<CR>") + end +} diff --git a/lua/core/conf.lua b/lua/core/conf.lua deleted file mode 100644 index fe24b8d..0000000 --- a/lua/core/conf.lua +++ /dev/null @@ -1,81 +0,0 @@ -local pickers = require("telescope.pickers") -local finders = require("telescope.finders") -local previewers = require("telescope.previewers") -local conf = require("telescope.config").values -local actions = require("telescope.actions") -local action_state = require("telescope.actions.state") - -local M = {} - -local function genmenu() - local list = {} - local function add(name, plug) - if not plug then - table.insert(list, name) - elseif package.loaded[plug] then - table.insert(list, name) - end - end - - add('Edit Config', nil) - add('Update Plugins', 'dep') - add('Keybinds', 'telescope') - add('Colorscheme', 'telescope') - - return list -end - -function M.configmenu() - pickers.new({ - prompt_title = "Nvim Config Menu", - finder = finders.new_table { results = genmenu() }, - sorter = conf.generic_sorter(), - previewer = previewers.new_buffer_previewer { - define_preview = function(self, entry) - local lines = { - 'a' - } - if entry.value == "Edit Config" then - lines = misc.readf(vim.fn.stdpath('config')..'/init.lua') - local ft = vim.filetype.match({ - filename = os.getenv('XDG_CONFIG_HOME')..'/nvim/init.lua' }) - require("telescope.previewers.utils").highlighter(self.state.bufnr, ft) - elseif entry.value == "Colorscheme" then - lines = vim.fn.getcompletion('', 'color') - for k, v in pairs(lines) do - if v.find(v, '.ext') then - table.remove(lines, k) - break - end - end - end - vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines) - end - }, - - attach_mappings = function(bufnr, map) - actions.select_default:replace(function() - actions.close(bufnr) - local selection = action_state.get_selected_entry() - if selection[1] == 'Edit Config' then - vim.cmd('e '..vim.fn.stdpath('config')..'/init.lua') - elseif selection[1] == 'Update Plugins' then - require('dep').sync() - if package.loaded['nvim-treesitter'] then - vim.cmd('TSUpdate') - end - if package.loaded['mason'] then - require('mason.api.command').MasonUpdate() - end - elseif selection[1] == 'Keybinds' then - require('telescope.builtin').keymaps() - elseif selection[1] == 'Colorscheme' then - require('core.theme').switcher() - end - end) - return true - end, - }):find() -end - -return M diff --git a/lua/core/harpoon.lua b/lua/core/harpoon.lua deleted file mode 100644 index ce68bdd..0000000 --- a/lua/core/harpoon.lua +++ /dev/null @@ -1,61 +0,0 @@ -local pickers = require("telescope.pickers") -local finders = require("telescope.finders") -local conf = require("telescope.config").values -local actions = require("telescope.actions") -local action_set = require("telescope.actions.set") -local action_state = require("telescope.actions.state") -local harpoon = require('harpoon') - -local M = {} - -function M.switcher() - local filepaths = {} - for _, item in ipairs(harpoon:list().items) do - table.insert(filepaths, item.value) - end - - pickers.new({ - prompt_title = "Harpoon", - finder = finders.new_table { results = filepaths }, - sorter = conf.generic_sorter(), - previewer = conf.file_previewer {}, - attach_mappings = function(prompt_bufnr, map) - actions.move_selection_previous:replace(function() - action_set.shift_selection(prompt_bufnr, -1) - end) - actions.move_selection_next:replace(function() - action_set.shift_selection(prompt_bufnr, 1) - end) - - -- remove harpoon item - vim.keymap.set("i", "<C-a>", function() - if action_state.get_selected_entry() then - for i, v in ipairs(filepaths) do - if v == action_state.get_selected_entry()[1] then - harpoon:list():removeAt(i) - actions.close(prompt_bufnr) - M.switcher() - end - end - end - end) - - -- select items, and open buffer - vim.keymap.set("i", "<C-s>", function() - if action_state.get_selected_entry() then - actions.close(prompt_bufnr) - vim.cmd("split "..action_state.get_selected_entry()[1]) - end - end, { buffer = true, remap = true }) - actions.select_default:replace(function() - if action_state.get_selected_entry() then - actions.close(prompt_bufnr) - vim.cmd("e "..action_state.get_selected_entry()[1]) - end - end) - return true - end - }):find() -end - -return M diff --git a/lua/core/misc.lua b/lua/core/misc.lua index b96855b..2dcf3fe 100644 --- a/lua/core/misc.lua +++ b/lua/core/misc.lua @@ -1,43 +1,184 @@ local M = {} +--- vim.notify title M.appid = "Nvim Config" +--- safe version of require +---@param fn string name of file to include +---@return any +function M.include(fn) + local ok, r = pcall(require, fn) + if not ok then + vim.notify('Could not find "'..fn..'": '..r, vim.log.levels.WARN, { title = M.appid }) + return ok + end + return r +end + +--- loop through files in directory +---@param path string absolute path of directory to be looped through +---@param body function function to use on every recursion of the loop +---@param ext string? desired file extension of files to be returned from directory +function M.loopf(path, body, ext) + ext = ext and [[v:val =~ '\.]]..ext..[[$']] or nil + for _, file in ipairs(vim.fn.readdir(path, ext)) do + body(file) + end +end + +--- set colorscheme +---@param name string name of colorscheme function M.colorscheme(name) vim.cmd('colorscheme '..name) - for k, v in pairs(vim.fn.getcompletion('', 'color')) do + for _, v in pairs(vim.fn.getcompletion('', 'color')) do if v == name..'.ext' then vim.cmd('colorscheme '..name..'.ext') end end end -function M.replaceword(old, new) - local conf = vim.fn.stdpath("config").."/lua/conf/".."opts.lua" - local f = io.open(conf, "r") - if not f then return end - local new_content = f:read("*all"):gsub(old, new) - f:close() +--- extend vim.kemap.set +---@param mode string|table mode for the keymap +---@param bind string|table keymap +---@param cmd function|string command to run +---@param opts table? keymap options +function M.map(mode, bind, cmd, opts) + opts = opts or {} + opts['noremap'] = true + opts['silent'] = true - f = io.open(conf, "w") - if not f then return end - f:write(new_content) - f:close() + if type(bind) == 'table' then + for i in pairs(bind) do + vim.keymap.set(mode, bind[i], cmd, opts) + end + elseif type(bind) == 'string' then + vim.keymap.set(mode, bind, cmd, opts) + end end -function M.include(fn) - if not pcall(require, fn) then - vim.notify('Could not find "'..fn, vim.log.levels.WARN..'"', { title = M.appid }) +--- a small map wrapper to easily create local buffer mappings +---@param mode string|table mode for the keymap +---@param bind string|table keymap +---@param cmd function|string command to run +---@param opts table? keymap options +function M.map_local(mode, bind, cmd, opts) + opts = opts or {} + opts["buffer"] = 0 + M.map(mode, bind, cmd, opts) +end + +--- extend vim.api.nvim_create_autocmd +---@param event string|table event or events +---@param opts table options +function M.auto(event, opts) + vim.api.nvim_create_autocmd(event, opts) +end + +--- extend auto group +---@param name string name of the autogroup +---@param opts table? table of options +function M.augroup(name, opts) + opts = opts or {} + vim.api.nvim_create_augroup(name, opts) +end + +--- extend vim.api.nvim_set_hl +---@param group string|table highlight group +---@param opts table highlight options +---@param namespace? number highlight space +function M.highlight(group, opts, namespace) + namespace = namespace or 0 + + if type(group) == 'table' then + for i in pairs(group) do + vim.api.nvim_set_hl(namespace, group[i], opts) + end + elseif type(group) == 'string' then + vim.api.nvim_set_hl(namespace, group, opts) + end +end + +--- copy highlight group +---@param hlgroup string highlight group to copy +---@param namespace? number highlight space +---@return table +function M.cpyhl(hlgroup, namespace) + namespace = namespace or 0 + + local ok, hl = pcall(vim.api.nvim_get_hl, namespace, { + name = hlgroup, + create = false + }) + if not ok then + return {} + end + + for _, key in pairs({"foreground", "background", "special"}) do + if hl[key] then + hl[key] = string.format("#%06x", hl[key]) + end end + return hl end -function M.readf(fn) - local f = io.open(fn, "r") - if not f then return nil end - local tab = {} - for l in f:lines() do - table.insert(tab, l) +--- highlight something with some highlight group for a certain amount of time +---@param opts table? options +--- example: +--- ```lua +--- { +--- -- highlight group to use +--- hl = "IncSearch", +--- +--- -- # of ms to stay highlighted for +--- timeout = 250, +--- +--- -- line to highlight +--- line = vim.api.nvim_win_get_cursor(0)[1], +--- +--- -- range to highlight if this is used line will be ignored +--- range = { +--- { 0, 0 }, +--- { 0, 0 } +--- } +--- } +--- ``` +--- opts is optional and if empty will simply highlight the current line for +--- 250ms using IncSearch as the highlight group +function M.timeout_highlight(opts) + opts = opts or {} + opts.hl = opts.hl or "IncSearch" + opts.timeout = opts.timeout or 250 + if type(opts.range) ~= "table" or type(opts.range[1]) ~= "table" or + type(opts.range[2]) ~= "table" then + local curline = opts.line or vim.api.nvim_win_get_cursor(0)[1] + opts.range = { + { curline - 1, 0 }, + { curline, 0 } + } end - return tab + + local namespaceid = vim.api.nvim_create_namespace("timeout_highlight") + + -- timer code was happily stolen from neovim/runtime/lua/vim/highlight.lua :) + local timer, timer_cancel + + if timer then + timer:close() + assert(timer_cancel) + timer_cancel() + end + + -- set the highlight + vim.highlight.range(0, namespaceid, opts.hl, opts.range[1], opts.range[2], {}) + + timer_cancel = function() + timer = nil + timer_cancel = nil + pcall(vim.api.nvim_buf_clear_namespace, 0, namespaceid, 0, -1) + pcall(vim.api.nvim_win_remove_ns, 0, namespaceid) + end + + timer = vim.defer_fn(timer_cancel, opts.timeout) end return M diff --git a/lua/core/snippets/shorthands.lua b/lua/core/snippets/shorthands.lua new file mode 100644 index 0000000..d885ea2 --- /dev/null +++ b/lua/core/snippets/shorthands.lua @@ -0,0 +1,22 @@ +luasnip = require('luasnip') + +s = luasnip.snippet +sn = luasnip.snippet_node +t = luasnip.text_node +i = luasnip.insert_node +f = luasnip.function_node +c = luasnip.choice_node +d = luasnip.dynamic_node +r = luasnip.restore_node +l = require("luasnip.extras").lambda +rep = require("luasnip.extras").rep +p = require("luasnip.extras").partial +m = require("luasnip.extras").match +n = require("luasnip.extras").nonempty +dl = require("luasnip.extras").dynamic_lambda +fmt = require("luasnip.extras.fmt").fmt +fmta = require("luasnip.extras.fmt").fmta +types = require("luasnip.util.types") +conds = require("luasnip.extras.conditions") +conds_expand = require("luasnip.extras.conditions.expand") +ts_postfix = require("luasnip.extras.treesitter_postfix").treesitter_postfix diff --git a/lua/core/statusbar/components.lua b/lua/core/statusbar/components.lua deleted file mode 100644 index 0233e1b..0000000 --- a/lua/core/statusbar/components.lua +++ /dev/null @@ -1,325 +0,0 @@ -if not pcall(require, "el") then return end - -local job = require "plenary.job" -local el_sub = require "el.subscribe" - -local M = {} - -function M.extract_hl(spec) - if not spec or vim.tbl_isempty(spec) then return end - local hl_name, hl_opts = { "El" }, {} - for attr, val in pairs(spec) do - if type(val) == "table" then - table.insert(hl_name, attr) - assert(vim.tbl_count(val) == 1) - local hl, what = next(val) - local hlID = vim.fn.hlID(hl) - if hlID > 0 then - table.insert(hl_name, hl) - local col = vim.fn.synIDattr(hlID, what) - if col and #col > 0 then - table.insert(hl_name, what) - hl_opts[attr] = col - end - end - else - -- bold, underline, etc - hl_opts[attr] = val - end - end - hl_name = table.concat(hl_name, "_") - -- if highlight exists, verify it has - -- the correct colorscheme highlights - local newID = vim.fn.hlID(hl_name) - if newID > 0 then - for what, expected in pairs(hl_opts) do - local res = vim.fn.synIDattr(newID, what) - if type(expected) == "boolean" then - -- synIDattr returns '1' for boolean - res = res and res == "1" and true - end - if res ~= expected then - -- need to regen the highlight - -- print("color mismatch", hl_name, what, "e:", expected, "c:", res) - newID = 0 - end - end - end - if newID == 0 then - vim.api.nvim_set_hl(0, hl_name, hl_opts) - end - return hl_name -end - -local function set_hl(hls, s) - if not hls or not s then return s end - hls = type(hls) == "string" and { hls } or hls - for _, hl in ipairs(hls) do - if vim.fn.hlID(hl) > 0 then - return ("%%#%s#%s%%0*"):format(hl, s) - end - end - return s -end - -local function wrap_fnc(opts, fn) - return function(window, buffer) - -- buf_autocmd doesn't send win - if not window and buffer then - window = { win_id = vim.fn.bufwinid(buffer.bufnr) } - end - if opts.hide_inactive and window and - window.win_id ~= vim.api.nvim_get_current_win() then - return "" - end - return fn(window, buffer) - end -end - -function M.mode(opts) - opts = opts or {} - return wrap_fnc(opts, function(_, _) - local fmt = opts.fmt or "%s%s" - local mode = vim.api.nvim_get_mode().mode - local mode_data = opts.modes and opts.modes[mode] - local hls = mode_data and mode_data[3] - local icon = opts.hl_icon_only and set_hl(hls, opts.icon) or opts.icon - mode = mode_data and mode_data[1]:upper() or mode - mode = (fmt):format(icon or "", mode) - return not opts.hl_icon_only and set_hl(hls, mode) or mode - end) -end - -function M.git_branch(opts) - opts = opts or {} - return el_sub.buf_autocmd("el_git_branch", "BufEnter", - wrap_fnc(opts, function(_, buffer) - -- Try fugitive first as it's most reliable - local branch = vim.g.loaded_fugitive == 1 and - vim.fn.FugitiveHead() or nil - -- buffer can be null and code will crash with: - -- E5108: Error executing lua ... 'attempt to index a nil value' - if not buffer or not (buffer.bufnr > 0) then - return - end - -- fugitive is empty or not loaded, try gitsigns - if not branch or #branch == 0 then - local ok, res = pcall(vim.api.nvim_buf_get_var, - buffer.bufnr, "gitsigns_head") - if ok then branch = res end - end - -- last resort run git command - if not branch then - local j = job:new { - command = "git", - args = { "branch", "--show-current" }, - cwd = vim.fn.fnamemodify(buffer.name, ":h"), - } - - local ok, result = pcall(function() - return vim.trim(j:sync()[1]) - end) - if ok then - branch = result - end - end - - if branch and #branch > 0 then - local fmt = opts.fmt or "%s %s" - local icon = opts.icon or "" - return set_hl(opts.hl, (fmt):format(icon, branch)) - end - end)) -end - -local function git_changes_formatter(opts) - local specs = { - insert = { - regex = "(%d+) insertions?", - icon = opts.icon_insert or "+", - hl = opts.hl_insert, - }, - change = { - regex = "(%d+) files? changed", - icon = opts.icon_change or "~", - hl = opts.hl_change, - }, - delete = { - regex = "(%d+) deletions?", - icon = opts.icon_delete or "-", - hl = opts.hl_delete, - }, - } - return function(_, _, s) - local result = {} - for k, v in pairs(specs) do - local count = nil - if type(s) == "string" then - -- 'git diff --shortstat' output - -- from 'git_changes_all' - count = tonumber(string.match(s, v.regex)) - else - -- map from 'git_changes_buf' - count = s[k] - end - if count and count > 0 then - table.insert(result, set_hl(v.hl, ("%s%d"):format(v.icon, count))) - end - end - return table.concat(result, " ") - end -end - --- requires gitsigns -function M.git_changes_buf(opts) - opts = opts or {} - local formatter = opts.formatter or git_changes_formatter(opts) - return wrap_fnc(opts, function(window, buffer) - local stats = {} - if buffer and buffer.bufnr > 0 then - local ok, res = pcall(vim.api.nvim_buf_get_var, - buffer.bufnr, "vgit_status") - if ok then stats = res end - end - if buffer and buffer.bufnr > 0 then - local ok, res = pcall(vim.api.nvim_buf_get_var, - buffer.bufnr, "gitsigns_status_dict") - if ok then stats = res end - end - local counts = { - insert = stats.added > 0 and stats.added or nil, - change = stats.changed > 0 and stats.changed or nil, - delete = stats.removed > 0 and stats.removed or nil, - } - if not vim.tbl_isempty(counts) then - local fmt = opts.fmt or "%s" - local out = formatter(window, buffer, counts) - return out and fmt:format(out) or nil - else - -- el functions that return a - -- string must not return nil - return "" - end - end) -end - -function M.git_changes_all(opts) - opts = opts or {} - local formatter = opts.formatter or git_changes_formatter(opts) - return el_sub.buf_autocmd("el_git_changes", "BufWritePost", - wrap_fnc(opts, function(window, buffer) - if not buffer or - not (buffer.bufnr > 0) or - vim.bo[buffer.bufnr].bufhidden ~= "" or - vim.bo[buffer.bufnr].buftype == "nofile" or - vim.fn.filereadable(buffer.name) ~= 1 then - return - end - - local j = job:new { - command = "git", - args = { "diff", "--shortstat" }, - -- makes no sense to run for one file as - -- 'file(s) changed' will always be 1 - -- args = { "diff", "--shortstat", buffer.name }, - cwd = vim.fn.fnamemodify(buffer.name, ":h"), - } - - local ok, git_changes = pcall(function() - return formatter(window, buffer, vim.trim(j:sync()[1])) - end) - - if ok then - local fmt = opts.fmt or "%s" - return git_changes and fmt:format(git_changes) or nil - end - end)) -end - -function M.lsp_srvname(opts) - local fmt = opts.fmt or "%s" - local icon = opts.icon or "" - local names = "" - vim.lsp.for_each_buffer_client(0, function(client) - if names ~= "" then names = names..", " end - names = names..client.name - end) - return icon..fmt:format(names) -end - -local function diag_formatter(opts) - return function(_, buffer, counts) - local items = {} - local icons = { - ["errors"] = { opts.icon_err or "x", opts.hl_err or "DiagnosticError"}, - ["warnings"] = { opts.icon_warn or "!", opts.hl_warn or "DiagnosticWarn"}, - ["infos"] = { opts.icon_info or "i", opts.hl_info or "DiagnosticInfo"}, - ["hints"] = { opts.icon_hint or "h", opts.hl_hint or "DiagnosticHint"}, - } - for _, k in ipairs({ "errors", "warnings", "infos", "hints" }) do - if counts[k] > 0 then - table.insert(items, - set_hl(icons[k][2], ("%s:%s"):format(icons[k][1], counts[k]))) - end - end - local fmt = opts.fmt or "%s" - if vim.tbl_isempty(items) then - return "" - else - return fmt:format(table.concat(items, " ")) - end - end -end - -local function get_buffer_counts(diagnostic, _, buffer) - local counts = { 0, 0, 0, 0 } - local diags = diagnostic.get(buffer.bufnr) - if diags and not vim.tbl_isempty(diags) then - for _, d in ipairs(diags) do - if tonumber(d.severity) then - counts[d.severity] = counts[d.severity] + 1 - end - end - end - return { - errors = counts[1], - warnings = counts[2], - infos = counts[3], - hints = counts[4], - } -end - -function M.diagnostics(opts) - opts = opts or {} - local formatter = opts.formatter or diag_formatter(opts) - return el_sub.buf_autocmd("el_buf_diagnostic", "LspAttach,DiagnosticChanged", - wrap_fnc(opts, function(window, buffer) - return formatter(window, buffer, get_buffer_counts(vim.diagnostic, window, buffer)) - end)) -end - -function M.line(opts) - opts = opts or {} - local fmt = opts.fmt or "%s" - return wrap_fnc(opts, function(_, _) - local al = vim.api.nvim_buf_line_count(0) - local cl = vim.api.nvim_win_get_cursor(0)[1] - return (fmt):format(cl.."/"..al.." "..math.floor((cl / al) * 100).."%%") - end) -end - -function M.fn_tail(opts) - opts = opts or {} - local fmt = opts.fmt or "%s" - local hl_exec = opts.hl_exec or "Character" - - local fn = vim.fn.expand("%:t") - if vim.fn.getftype(fn) == "file" then - if string.match(vim.fn.getfperm(fn), 'x', 3) then - return (fmt):format(set_hl(hl_exec, fn)) - end - end - return (fmt):format(fn) -end - -return M diff --git a/lua/core/theme.lua b/lua/core/theme.lua deleted file mode 100644 index f6598ac..0000000 --- a/lua/core/theme.lua +++ /dev/null @@ -1,80 +0,0 @@ -local pickers = require("telescope.pickers") -local finders = require("telescope.finders") -local previewers = require("telescope.previewers") -local conf = require("telescope.config").values -local actions = require("telescope.actions") -local action_set = require("telescope.actions.set") -local action_state = require("telescope.actions.state") -local misc = require('core.misc') - -local M = {} - -function M.switcher() - local bufnr = vim.api.nvim_get_current_buf() - - -- show current buffer content in previewer - local colors = vim.fn.getcompletion('', 'color') - for k, v in pairs(colors) do - if v.find(v, '.ext') then - table.remove(colors, k) - break - end - end - - -- our picker function: colors - pickers.new({ - prompt_title = "Set Nvim Colorscheme", - finder = finders.new_table { results = colors }, - sorter = conf.generic_sorter(), - previewer = previewers.new_buffer_previewer { - define_preview = function(self, entry) - -- add content - local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) - vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines) - - -- add syntax highlighting in previewer - local ft = (vim.filetype.match { buf = bufnr } or "diff"):match "%w+" - require("telescope.previewers.utils").highlighter(self.state.bufnr, ft) - end - }, - - attach_mappings = function(prompt_bufnr, map) - -- reload theme while typing - vim.schedule(function() - vim.api.nvim_create_autocmd("TextChangedI", { - buffer = prompt_bufnr, - callback = function() - if action_state.get_selected_entry() then - misc.colorscheme(action_state.get_selected_entry()[1]) - end - end, - }) - end) - - -- reload theme on cycling - actions.move_selection_previous:replace(function() - action_set.shift_selection(prompt_bufnr, -1) - misc.colorscheme(action_state.get_selected_entry()[1]) - end) - actions.move_selection_next:replace(function() - action_set.shift_selection(prompt_bufnr, 1) - misc.colorscheme(action_state.get_selected_entry()[1]) - end) - - -- reload theme on selection - actions.select_default:replace(function() - if action_state.get_selected_entry() then - actions.close(prompt_bufnr) - misc.colorscheme(action_state.get_selected_entry()[1]) - - -- make the colorscheme swap persistant - misc.replaceword("misc.colorscheme%(.+%)", - "misc.colorscheme('"..action_state.get_selected_entry()[1].."')") - end - end) - return true - end, - }):find() -end - -return M diff --git a/lua/snippet/c.lua b/lua/snippet/c.lua deleted file mode 100644 index 7ef2e51..0000000 --- a/lua/snippet/c.lua +++ /dev/null @@ -1,79 +0,0 @@ -ls.add_snippets('c', { - s('trip', { - -- cond ? then : else statment - i(1, 'cond'), t(' ? '), i(2, 'then'), t(' : '), i(3, 'else') - }), - - s('stdlibs', { - -- the normal stuff - t('#include <stdio.h>'), - t({'', '#include <stdlib.h>'}) - }), - - s('die', { - -- message provieder when program is exiting - t({ - 'void die(const char *fmt, ...) {', '', - 'va_list ap;', - '', - 'va_start(ap, fmt);', - 'vfprintf(stderr, fmt, ap);', - 'va_end(ap);', - '', - [[if (fmt[0] && fmt[strlen(fmt)-1] == ':') {]], - [[ fputc(' ', stderr);]], - ' perror(NULL);', - '} else', - [[ fputc('\n', stderr);]], - ' exit(1);', - '}', - }) - }), - - s({ - name = 'get them opts!', - trig = 'getopt', - dscr = 'standard argument parser', - }, - fmta( - [[ - int c; - - while ((c = getopt(argc, argv, "<OPTS>")) != -1) { - switch (c) { - case '<OPT1>': <OPT1RUN> break; - default: <DEFRUN> break; - } - } - ]], - { - OPTS = i(1, 'h'), - OPT1 = i(2, 'h'), - OPT1RUN = i(3, 'printf("help text\\n");'), - DEFRUN = i(4, 'printf("run %s -h for help\\n", argv[0]); return 1;'), - } - ) - ), - s({ - name = 'Variadic function parser', - trig = 'infinite vars', - dscr = 'Parse an infinite number of arguments passed to a function', - }, - { - t({ - "/*", - " * NOTE: the function must have a int before the ... argument", - " * and you need to include <stdarg.h> for this to work", - " */", - "va_list ptr;", - "va_start(ptr, ", i(1, "n"), - ");", - "for (int i = 0; i < ", ri(1), - "; i++) {", - i(2), - "}", - "va_end(ptr);", - }), - } - ) -}) diff --git a/lua/snippet/lua.lua b/lua/snippet/lua.lua deleted file mode 100644 index c5466ff..0000000 --- a/lua/snippet/lua.lua +++ /dev/null @@ -1,14 +0,0 @@ -ls.add_snippets('lua', { - s({ - name = "local require", - trig = "req", - dscr = "simple lua require" - }, - fmt("local {} = require('{}')", - { - i(1, "default"), - ri(1), - } - ) - ) -}) diff --git a/lua/snippet/makefile.lua b/lua/snippet/makefile.lua deleted file mode 100644 index d15ef8d..0000000 --- a/lua/snippet/makefile.lua +++ /dev/null @@ -1,41 +0,0 @@ -ls.add_snippets('make', { - s({ - name = "Start Makefile", - trig = "make", - dscr = "simple starter make file" - }, - fmta( - [[ - # flags and incs - CFLAGS = <FLAGS> - INCS = <MAIN>.c - - PREFIX = <PREFIX> - - # compiler and linker - CC = cc - - all: <MAINA> - <MAINA>: <MAINA>.o - $(CC) <MAINA>.o $(CFLAGS) -o $@ - <MAINA>.o: $(INCS) - - clean: - rm -f <MAINA> *.o - - install: <MAINA> - mkdir -p $(PREFIX)/bin - cp -f <MAINA> $(PREFIX)/bin - chmod 755 $(PREFIX)/bin/<MAINA> - uninstall: <MAINA> - rm -f $(PREFIX)/bin/<MAINA> - ]], - { - FLAGS = i(1, "-Wall"), - MAIN = i(2, "main"), - PREFIX = i(3, "/usr/local"), - MAINA = ri(2), - } - ) - ), -}) diff --git a/lua/snippet/shorthands.lua b/lua/snippet/shorthands.lua deleted file mode 100644 index 05453bd..0000000 --- a/lua/snippet/shorthands.lua +++ /dev/null @@ -1,31 +0,0 @@ -ls = require("luasnip") -s = ls.snippet -sn = ls.snippet_node -isn = ls.indent_snippet_node -t = ls.text_node -i = ls.insert_node -f = ls.function_node -c = ls.choice_node -d = ls.dynamic_node -r = ls.restore_node -events = require("luasnip.util.events") -ai = require("luasnip.nodes.absolute_indexer") -extras = require("luasnip.extras") -l = extras.lambda -rep = extras.rep -p = extras.partial -m = extras.match -n = extras.nonempty -dl = extras.dynamic_lambda -fmt = require("luasnip.extras.fmt").fmt -fmta = require("luasnip.extras.fmt").fmta -conds = require("luasnip.extras.expand_conditions") -postfix = require("luasnip.extras.postfix").postfix -types = require("luasnip.util.types") -parse = require("luasnip.util.parser").parse_snippet - --- Repeat Insernode text --- @param insert_node_id The id of the insert node to repeat (the first line from) -ri = function (insert_node_id) - return f(function (args) return args[1][1] end, insert_node_id) -end diff --git a/lua/snippets/c.lua b/lua/snippets/c.lua new file mode 100644 index 0000000..b1ca713 --- /dev/null +++ b/lua/snippets/c.lua @@ -0,0 +1,48 @@ +require('core.snippets.shorthands') + +return { + -- method snippet + s("main", { + c(1, { + t(""), + t("static "), + }), + t("int "), + t("main"), + t("("), + c(2, { + t("int argc, char *argv[]"), + i(1, "void"), + }), + t(")"), + t({ " {", "\t" }), + i(0), + t({ "", "}" }), + }), + + -- function snippet + s("fn", { + c(1, { + t("void"), + t("char"), + t("int"), + t("short"), + t("long"), + t("double"), + t("float"), + i(nil, "myType"), + }), + t({ "", "" }), + c(2, { + t(""), + t("*") + }), + i(3, "myFunc"); + t("("), + i(4), + t(")"), + t({ "", "{", "\t" }), + i(0), + t({ "", "}" }), +}) +} diff --git a/lua/snippets/java.lua b/lua/snippets/java.lua new file mode 100644 index 0000000..8424628 --- /dev/null +++ b/lua/snippets/java.lua @@ -0,0 +1,110 @@ +require('core.snippets.shorthands') + +local function file_name(args, parent, user_args) + return vim.fn.expand("%:t:r") +end + +return { + -- method snippet + s("fn", { + c(1, { + t("public "), + t("private "), + }), + c(2, { + t("void"), + t("String"), + t("char"), + t("int"), + t("double"), + t("boolean"), + i(nil, "myType"), + }), + t(" "), + i(3, "myFunc"), + t("("), + i(4), + t(")"), + c(5, { + t(""), + sn(nil, {t({ "", " throws " }), i(1)}), + }), + t({ " {", "\t" }), + i(0), + t({ "", "}" }), + }), + + -- constructor snippet + s("constr", { + c(1, { + t("public "), + t("private "), + t("protected ") + }), + f(file_name, {}), + t("("), + i(2), + t(")"), + c(3, { + t(""), + sn(nil, {t({ "", " throws " }), i(1)}), + }), + t({ " {", "\t" }), + i(0), + t({ "", "}" }), + }), + + -- class snippet + s("class", { + c(1, { + t("public "), + t("private "), + t("protected ") + }), + c(2, { + t("class "), + t("interface ") + }), + f(file_name, {}), + c(3, { + t(" "), + sn(nil, { t({" implements "}), i(1), t(" ") }), + sn(nil, { t({" extends "}), i(1), t(" ") }), + }), + t({ "{", "\t" }), + i(0), + t({ "", "}" }), + }), + + -- pacakge snippet + s("package", { + t("package "), + f(function(args, parent, user_args) + -- get path + local dir = vim.fn.expand("%:h") + -- remove prefix + dir = dir:gsub("src/main/java/", "") + -- convert to package path + dir = dir:gsub("/", ".") + + return dir + end, {}), + t(";"), + t({ "", "", "" }) + }), + + -- try, catch, finally snippet + s("try", { + t({"try {", "\t"}), + i(1), + t({"", "} catch ("}), + i(2, "Error e"), + t({") {", "\t"}), + i(3), + t({"", "}"}), + c(4, { + t(""), + sn(nil, { t({" finally {", "\t"}), i(1), t({"", "}"}) }) + }) + }) +} diff --git a/lua/snippets/make.lua b/lua/snippets/make.lua new file mode 100644 index 0000000..fefdf92 --- /dev/null +++ b/lua/snippets/make.lua @@ -0,0 +1,47 @@ +require('core.snippets.shorthands') + +return { + -- basic make template snippet + s("make", { + t({ "PKG_CONFIG = pkg-config", "CC = cc", "VERSION = " }), + i(1, "0.1"), + t({ "", "", "# flags and incs", "PKGS = " }), + i(2), + t({ "", "CFLAGS = -DVERSION=\\\"$(VERSION)\\\" -Wall" }), + i(3), + t({ "", "LIBS = `$(PKG_CONFIG) --libs --cflags $(PKGS)`" }), + i(4), + t({ "", "", "PREFIX = " }), + i(5, "/usr/local"), + t({ "", "MANDIR = $(PREFIX)/share/man" }), + t({ "", "", "all: " }), + i(6, "main"), + t({ "", "" }), + rep(6), + t(": "), + rep(6), + t({ ".o", "\t$(CC) *.o $(CFLAGS) $(LIBS) -o $@", "" }), + rep(6), + t(".o: "), + rep(6), + t({ ".c", "", "clean:", "\trm -f " }), + rep(6), + t({ " *.o", "", "install: " }), + rep(6), + t({ "", "\tmkdir -p $(PREFIX)/bin", "\tcp -f " }), + rep(6), + t({ " $(PREFIX)/bin", "\tchmod 755 $(PREFIX)/bin/" }), + rep(6), + t({ "", "\tmkdir -p $(MANDIR)/man1", "\tcp -f " }), + rep(6), + t({ ".1 $(MANDIR)/man1", "\tchmod 644 $(MANDIR)/man1/" }), + rep(6), + t({ ".1", "", "uninstall: " }), + rep(6), + t({ "", "\trm -f $(PREFIX)/bin/" }), + rep(6), + t(" $(MANDIR)/man1/"), + rep(6), + t(".1") + }) +} diff --git a/lua/snippets/norg.lua b/lua/snippets/norg.lua new file mode 100644 index 0000000..d96a471 --- /dev/null +++ b/lua/snippets/norg.lua @@ -0,0 +1,28 @@ +require('core.snippets.shorthands') + +local function file_name(args, parent, user_args) + return vim.fn.expand("%:t:r") +end + +return { + -- header level 1, usually this has the same name as the file + s("h1", { + t("* "), + c(1, { + f(file_name, {}), + i(1, "header") + }) + }), + + -- link snippet + s("link", { + t("{"), + c(1, { + sn(nil, { t({":$/"}), i(1, "path to file"), t(":") }), + i(1, "https://example.com") + }), + t("}["), + i(2, "description"), + t("]") + }) +} diff --git a/lua/snippets/openscad.lua b/lua/snippets/openscad.lua new file mode 100644 index 0000000..c430f2d --- /dev/null +++ b/lua/snippets/openscad.lua @@ -0,0 +1,40 @@ +require('core.snippets.shorthands') + +return { + -- translate snippet + s("t", { + t("translate([ "), + i(1, "0"), + t(", "), + i(2, "0"), + t(", "), + i(3, "0"), + t({ " ]) {", "\t" }), + i(0), + t({ "", "}" }) + }), + + -- rotate snippet + s("r", { + t("rotate([ "), + i(1, "0"), + t(", "), + i(2, "0"), + t(", "), + i(3, "0"), + t({ " ]) {", "\t" }), + i(0), + t({ "", "}" }) + }), + + -- cube snippet + s("c", { + t("cube([ "), + i(1, "0"), + t(", "), + i(2, "0"), + t(", "), + i(3, "0"), + t(" ]);") + }), +} diff --git a/lua/snippets/php.lua b/lua/snippets/php.lua new file mode 100644 index 0000000..93713a4 --- /dev/null +++ b/lua/snippets/php.lua @@ -0,0 +1,9 @@ +require('core.snippets.shorthands') + +return { + s("php", { + t({ "<?php", "\t" }), + i(1), + t({ "", "?>" }) + }) +} |