diff --git a/.lua-format b/.lua-format index 53cb625..50bb10d 100644 --- a/.lua-format +++ b/.lua-format @@ -3,6 +3,3 @@ column_limit: 100 keep_simple_function_one_line: false spaces_inside_table_braces: true chop_down_table: true -# chop_down_parameter: true -# break_after_functioncall_lp: true -# break_before_functioncall_rp: true diff --git a/dotfiles/neovim/.neoconf.json b/dotfiles/neovim/.neoconf.json index 9c389ef..a0d5a68 100644 --- a/dotfiles/neovim/.neoconf.json +++ b/dotfiles/neovim/.neoconf.json @@ -10,7 +10,7 @@ "library": { "enabled": true, "types": true, - "plugins": true, + "plugins": false, "runtime": true } } diff --git a/dotfiles/neovim/ftplugin/tex.lua b/dotfiles/neovim/ftplugin/tex.lua index 3698f65..5f21b10 100644 --- a/dotfiles/neovim/ftplugin/tex.lua +++ b/dotfiles/neovim/ftplugin/tex.lua @@ -1,5 +1,5 @@ local A = require("my.abbreviations") -local AB = require("my.plugins.abolish") +local scrap = require("scrap") require("my.helpers.wrapMovement").setup() @@ -42,44 +42,13 @@ local abbreviations = { { "gamma", "\\gamma" }, { "lam", "\\lambda" }, { "nuls", "\\varnothing" }, -- Other fancy symvols - { "ints", "\\mathbb{Z}" }, - { "nats", "\\mathbb{N}" }, - { "rats", "\\mathbb{Q}" }, - { "irats", "\\mathbb{I}" }, - { "rrea", "\\mathbb{R}" }, - { "ppri", "\\mathbb{P}" }, - { "ffie", "\\mathbb{F}" }, - { "ccom", "\\mathbb{C}" }, -- Exponents - { "ei", "^{-1}" }, - { "e0", "^{0}" }, - { "e1", "^{1}" }, - { "e2", "^{2}" }, - { "e3", "^{3}" }, - { "e4", "^{4}" }, - { "en", "^{n}" }, - { "etn", "^{-}" }, - { "ett", "^{t}" }, - { "tmat", "^{T}" }, -- Tranpose of a matrix - { "cmat", "^{*}" }, -- Conjugate of a matrix + + { "tmat", "^T" }, -- Tranpose of a matrix + { "cmat", "^*" }, -- Conjugate of a matrix { "ortco", "^{\\bot}" }, -- Orthogonal complement - { "etp", "^{+}" }, -- Subscripts - { "s0", "_{0}" }, - { "s1", "_{1}" }, - { "s2", "_{2}" }, - { "s3", "_{3}" }, - { "s4", "_{4}" }, - { "sn", "_{n}" }, -- Function calls - { "fx", "f(x)" }, - { "gx", "g(x)" }, - { "hx", "h(x)" }, - { "Px", "P(x)" }, - { "Pn", "P(n)" }, - { "foa", "f(a)" }, - { "goa", "g(a)" }, - { "hoa", "h(a)" }, - { "dfx", "f'(x)" }, - { "dgx", "g'(x)" }, - { "dhx", "h'(x)" }, -- Basic commands + { "sinter", "^{\\circ}" }, -- Interior of a set + + -- Basic commands { "mangle", "\\measuredangle" }, { "aangle", "\\angle" }, @@ -111,7 +80,6 @@ local abbreviations = { { "comp", "\\circ" }, { "mul", "\\cdot" }, { "smul", "\\times" }, - { "texpl", "&& \\text{}" }, { "card", "\\#" }, { "div", "\\|" }, { "ndiv", "\\not\\|\\:" }, @@ -120,29 +88,86 @@ local abbreviations = { { "rref", "reduced row echalon form" } } +---@type ExpansionOptions +local no_capitalization = { capitalized = false } + -- Todo: convert exponents and subscripts -- to use this more concise notation. +---@type ExpansionInput[] local abolishAbbreviations = { - { "eg{va,ve,p}{,s}", "eigen{value,vector,pair}{}" }, - { "ib{p,s}", "integration by {parts,substitution}" }, - { "mx{,s}", "matri{x,ces}" }, + -- General phrases { "thrf", "therefore" }, - { "dete{,s}", "determinant{}" }, { "bcla", "by contradiction let's assume" }, + { "wlg", "without loss of generality" }, + + -- Calculus + { "ib{p,s}", "integration by {parts,substitution}" }, + + -- Linear algebra + { "eg{va,ve,p}{,s}", "eigen{value,vector,pair}{}" }, + { "mx{,s}", "matri{x,ces}" }, + { "dete{,s}", "determinant{}" }, { "ort{n,g}", "orto{normal,gonal}" }, { "l{in,de}", "linearly {independent,dependent}" }, - { "wlg", "without loss of generality" }, -- My own operator syntax: -- - Any operator can be prefixed with "a" to -- align in aligned mode -- - Any operator can be prefixed with cr to -- start a new line and align in aligned mode - { "{cr,a,}{eq,neq,leq,geq,lt,gt}", "{\\\\\\&,&,}{=,\\neq,\\leq,\\geq,<,>}" } + { + "{cr,a,}{eq,neq,leq,geq,lt,gt}", + "{\\\\\\&,&,}{=,\\neq,\\leq,\\geq,<,>}", + options = no_capitalization + }, + + -- Exponents and subscripts: + -- {operation}{argument} + -- - operation = e (exponent) | s (subscript) + -- - argument = t{special} | {basic} + -- - basic = 0-9|n|i|t|k + -- - special = + -- - "p" => + + -- - "m" => - + -- - "i" => -1 + { + "{e,s}{{0,1,2,3,4,5,6,7,8,9,n,i,t,k},t{i,m,p}}", + "{^,_}{{},{\\{-1\\},-,+}}", + options = no_capitalization + }, + + -- Set symbols + -- - nats => naturals + -- - ints => integers + -- - rats => rationals + -- - irats => irationals + -- - rrea => reals + -- - comp => complex + -- - ppri => primes + -- - ffie => fields + { + "{nats,ints,rats,irats,rrea,comp,ppri,ffie}", + "\\mathbb\\{{N,Z,Q,I,R,C,P,F}\\}", + options = no_capitalization + }, + + -- Function calls: + -- {function-name}{modifier?}{argument} + -- + -- - function-name = f/g/h/P + -- - modifier: + -- - d => derivative + -- - 2 => squared + -- - 3 => cubed + -- - i => inverse + -- - argument = x/a/t/i/n/k + { "{f,g,h,P}{d,2,3,i,}{x,a,t,i,n,k}", "{}{',^2,^3,^\\{-1\\},}({})" } } +local expanded = scrap.expand_many(abolishAbbreviations) + A.manyLocalAbbr(abbreviations) -AB.abolishMany(abolishAbbreviations) +A.manyLocalAbbr(expanded) vim.keymap.set("n", "lc", "VimtexCompile", { desc = "Compile current buffer using vimtex", buffer = true }) diff --git a/dotfiles/neovim/init.lua b/dotfiles/neovim/init.lua index f5afbeb..c9874d5 100644 --- a/dotfiles/neovim/init.lua +++ b/dotfiles/neovim/init.lua @@ -1 +1,2 @@ +-- vim.opt.runtimepath:prepend(os.getenv("LAZY_NVIM_PATH")) require("my.init").setup() diff --git a/dotfiles/neovim/lua/my/helpers.lua b/dotfiles/neovim/lua/my/helpers.lua index 7c0b26f..e9158b5 100644 --- a/dotfiles/neovim/lua/my/helpers.lua +++ b/dotfiles/neovim/lua/my/helpers.lua @@ -1,7 +1,5 @@ local M = {} -function M.global(name, value) vim.g[name] = value end - function M.mergeTables(t1, t2) local t3 = {} diff --git a/dotfiles/neovim/lua/my/keymaps.lua b/dotfiles/neovim/lua/my/keymaps.lua index 3d4926a..87c11ac 100644 --- a/dotfiles/neovim/lua/my/keymaps.lua +++ b/dotfiles/neovim/lua/my/keymaps.lua @@ -3,23 +3,7 @@ local arpeggio = require("my.plugins.arpeggio") local M = {} -local function map(mode, lhs, rhs, opts) - if string.len(mode) > 1 then - for i = 1, #mode do - local c = mode:sub(i, i) - map(c, lhs, rhs, opts) - end - else - local options = helpers.mergeTables(opts, { noremap = true }) - vim.api.nvim_set_keymap(mode, lhs, rhs, options) - end -end - -function M.mapSilent(mode, lhs, rhs, opts) - local options = helpers.mergeTables(opts, { silent = true }) - map(mode, lhs, rhs, options) -end - +-- {{{ Helpers -- Performs a basic move operation function M.move(from, to, opts) vim.keymap.set("n", to, from, opts) @@ -32,18 +16,17 @@ function M.delimitedTextobject(from, to, name, perhapsOpts) vim.keymap.set({ "v", "o" }, "i" .. from, "i" .. to, opts) vim.keymap.set({ "v", "o" }, "a" .. from, "a" .. to, opts) end +-- }}} function M.setup() - -- I rarely use macro stuff + -- {{{ Free up q and Q M.move("q", "yq", { desc = "Record macro" }) M.move("Q", "yQ") - - -- Free these up for easymotion-style plugins - -- vim.keymap.set("n", "s", "") - -- vim.keymap.set("n", "S", "") - + -- }}} + -- {{{ Easier access to C^ M.move("", "a", { desc = "Go to previous file" }) - + -- }}} + -- {{{ Quit current buffer / all buffers vim.keymap.set({ "n", "v" }, "q", function() local buf = vim.api.nvim_win_get_buf(0) @@ -54,19 +37,35 @@ function M.setup() end, { desc = "Quit current buffer" }) vim.keymap.set("n", "Q", ":wqa", { desc = "Save all files and quit" }) + -- }}} + -- {{{ Replace word in file vim.keymap.set("n", "rw", ":%s//", { desc = "Replace word in file" }) - + -- }}} + -- {{{ Text objects M.delimitedTextobject("q", '"', "quotes") M.delimitedTextobject("a", "'", "'") M.delimitedTextobject("r", "[", "square brackets") + -- }}} + -- {{{Diagnostic keymaps + do + local opts = function(desc) + return { noremap = true, silent = true, desc = desc } + end - -- Create chords + vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts("Goto previous diagnostic")) + vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts("Goto next diagnostic")) + vim.keymap.set('n', 'J', vim.diagnostic.open_float, opts("Open current diagnostic")) + vim.keymap.set('n', 'J', vim.diagnostic.setloclist, opts("Set diagnostics loclist")) + end + -- }}} + -- {{{ Chords if arpeggio ~= nil then arpeggio.chordSilent("n", "ji", ":silent :write") -- Saving arpeggio.chord("i", "jk", "") -- Remap Esc to jk arpeggio.chord("nv", "cp", "\"+") -- Press cp to use the global clipboard end - + -- }}} + -- {{{ Set up which-key structure local status, wk = pcall(require, "which-key") if status then @@ -80,6 +79,7 @@ function M.setup() } }) end + -- }}} return M end diff --git a/dotfiles/neovim/lua/my/options.lua b/dotfiles/neovim/lua/my/options.lua index 5002b34..d01756e 100644 --- a/dotfiles/neovim/lua/my/options.lua +++ b/dotfiles/neovim/lua/my/options.lua @@ -3,43 +3,41 @@ local helpers = require("my.helpers") local M = {} function M.setup() - local opt = vim.opt -- to set options - -- Disable filetype.vim vim.g.do_filetype_lua = true vim.g.did_load_filetypes = false -- Basic options - opt.joinspaces = false -- No double spaces with join - opt.list = true -- Show some invisible characters - opt.cmdheight = 0 -- Hide command line when it's not getting used + vim.opt.joinspaces = false -- No double spaces with join + vim.opt.list = true -- Show some invisible characters + vim.opt.cmdheight = 0 -- Hide command line when it's not getting used -- Line numbers - opt.number = true -- Show line numbers - opt.relativenumber = true -- Relative line numbers + vim.opt.number = true -- Show line numbers + vim.opt.relativenumber = true -- Relative line numbers -- TODO: only do this for specific filestypes - opt.expandtab = true -- Use spaces for the tab char + vim.opt.expandtab = true -- Use spaces for the tab char - opt.scrolloff = 4 -- Lines of context - opt.shiftround = true -- Round indent - opt.shiftwidth = 2 -- Size of an indent - opt.termguicolors = true -- True color support + vim.opt.scrolloff = 4 -- Lines of context + vim.opt.shiftround = true -- Round indent + vim.opt.shiftwidth = 2 -- Size of an indent + vim.opt.termguicolors = true -- True color support - opt.ignorecase = true -- Ignore case - opt.smartcase = true -- Do not ignore case with capitals + vim.opt.ignorecase = true -- Ignore case + vim.opt.smartcase = true -- Do not ignore case with capitals - opt.smartindent = true -- Insert indents automatically + vim.opt.smartindent = true -- Insert indents automatically - opt.splitbelow = true -- Put new windows below current - opt.splitright = true -- Put new windows right of current + vim.opt.splitbelow = true -- Put new windows below current + vim.opt.splitright = true -- Put new windows right of current - opt.wrap = false -- Disable line wrap (by default) - opt.wildmode = { 'list', 'longest' } -- Command-line completion mode - opt.completeopt = { "menu", "menuone", "noselect" } + vim.opt.wrap = false -- Disable line wrap (by default) + vim.opt.wildmode = { 'list', 'longest' } -- Command-line completion mode + vim.opt.completeopt = { "menu", "menuone", "noselect" } -- Set leader - helpers.global("mapleader", " ") + vim.g.mapleader = " " -- Import other options require("my.options.folding").setup() diff --git a/dotfiles/neovim/lua/my/paq.lua b/dotfiles/neovim/lua/my/paq.lua index 61995a3..37e4258 100644 --- a/dotfiles/neovim/lua/my/paq.lua +++ b/dotfiles/neovim/lua/my/paq.lua @@ -66,6 +66,18 @@ function M.setup() "akinsho/toggleterm.nvim", -- cool terminal thingy "folke/noice.nvim", -- better ui for cmd line and other stuff "rcarriga/nvim-notify", -- better notifiaction ui + "hkupty/iron.nvim", -- repl support + "0styx0/abbremand.nvim", -- dependency for the next thing + "0styx0/abbreinder.nvim", -- reminds you of abbreviations + "ellisonleao/glow.nvim", -- md preview (in terminal) + "frabjous/knap", -- md preview + "tpope/vim-sleuth", -- automatically set options based on current file + "mateiadrielrafael/scrap.nvim", -- vim-abolish rewrite + "kevinhwang91/promise-async", -- required by nvim-ufo + "kevinhwang91/nvim-ufo", -- better folds and stuff + "ThePrimeagen/refactoring.nvim", -- refactoring + "gpanders/nvim-moonwalk", -- configure nvim in any language which compiles to lua + "teal-language/vim-teal", -- teal language support -- Git stuff "ruifm/gitlinker.nvim", -- generate permalinks for code diff --git a/dotfiles/neovim/lua/my/plugins/abolish.lua b/dotfiles/neovim/lua/my/plugins/abolish.lua index 0e34836..bb1ffbb 100644 --- a/dotfiles/neovim/lua/my/plugins/abolish.lua +++ b/dotfiles/neovim/lua/my/plugins/abolish.lua @@ -1,13 +1,227 @@ +local A = require("my.abbreviations") + local M = {} -function M.abolish(from, to) - vim.cmd(":Abolish " .. from .. " " .. to) +-- function M.abolish(from, to) +-- vim.cmd(":Abolish -buffer " .. from .. " " .. to) +-- end +-- +-- function M.abolishMany(many) +-- for _, entry in pairs(many) do M.abolish(entry[1], entry[2]) end +-- end + +local function concatTables(t1, t2) + assert(type(t1) == "table") + assert(type(t2) == "table") + + local t3 = {} + for i = 1, #t1 do t3[#t3 + 1] = t1[i] end + for i = 1, #t2 do t3[#t3 + 1] = t2[i] end + return t3 end -function M.abolishMany(many) - for _, entry in pairs(many) do - M.abolish(entry[1], entry[2]) +local function betterAbolish(unprocessed, context, out) + local from = unprocessed[1] or {} + local to = unprocessed[2] or {} + + assert(type(from) == "table" and type(to) == "table", + "Both arguments should be tables. Found " .. vim.inspect(from) .. " and " .. + vim.inspect(to) .. " instead.") + + -- print(vim.inspect({ context = context, unprocessed = unprocessed })) + + if #from == 0 and #to == 0 then + table.insert(out, context) + return + end + + for i = 1, 2, 1 do + local head = unprocessed[i][1] + if type(head) == "string" then + local context_clone = { context[1], context[2] } + + context_clone[i] = context_clone[i] .. head + + local unprocessed_clone = { unprocessed[1], unprocessed[2] } + unprocessed_clone[i] = { unpack(unprocessed[i], 2) } + + return betterAbolish(unprocessed_clone, context_clone, out) + end + end + + -- print(vim.inspect({ from, to, context })) + + assert(type(from[1]) == "table", vim.inspect(from) .. " starts with neither a table nor a string") + assert(type(to[1]) == "table", vim.inspect(to) .. " does not start with a table") + + for i = 1, #from[1], 1 do + local when = from[1][i] + local replacement = when + + if #to[1] > 0 then replacement = to[1][((i - 1) % #to[1]) + 1] end + + assert(type(when) == "table") + assert(type(replacement) == "table") + + local unprocessed_clone = { + concatTables(when, { unpack(from, 2) }), + concatTables(replacement, { unpack(to, 2) }) + } + + -- print(vim.inspect({ + -- unprocessed_clone = unprocessed_clone, + -- when = when, + -- replacement = replacement, + -- from = from, + -- to = to, + -- i = i + -- })) + + betterAbolish(unprocessed_clone, context, out) end end +function M.betterAbolish(from, to) + local result = {} + betterAbolish({ from, to }, { "", "" }, result) + + return result +end + +local function withCasing(input) + local out = {} + + for i = 1, #input, 1 do + local from = input[i][1] + local to = input[i][2] + + table.insert(out, { from, to }) + table.insert(out, { string.upper(from), string.upper(to) }) + + if #from and #to then + table.insert(out, { + string.upper(string.sub(from, 1, 1)) .. string.sub(from, 2), + string.upper(string.sub(to, 1, 1)) .. string.sub(to, 2) + }) + end + end + + return out +end + +---Parses the input for this plugin +---@param input string +---@param context {delimiters:{left:string,right:string},separator:string} +---@return nil|{positio:number,message:string} +---@return (string|table)[]|nil +local function parse(input, context) + local position = 1 + ---@type { start:number, contents:(string|table)[] }[] + local stack = { { start = position, contents = {} } } + + local function error(message, pos) + return { position = pos or position, message = message } + end + + local escaped = false + local escapedChars = { + ["\\"] = true, + [context.delimiters.left] = true, + [context.delimiters.right] = true + } + + -- When encountering {}, instead of treating it like a single + -- choice containing an empty string, we must treat it as an empty choice + -- + -- The specialEmpty arg tells us whether to consider such cases. + local function saveUp(specialEmpty) + local prev = stack[#stack - 1].contents + local current = stack[#stack] + + assert(type(prev[#prev]) == "table") + ---@cast prev table + + -- If specialEmpty is true (so we are processing a '}'), + -- we only want to keep empty strings (so those where #current.contents == 0) + -- if we've had a , before (so #prev[#prev] > 0) + if not specialEmpty or #current.contents > 0 or #prev[#prev] > 0 then + table.insert(prev[#prev], current.contents) + end + end + + while position <= string.len(input) do + local first = string.sub(input, position, position) + local next = string.sub(input, position + 1, position + 1) + local current = stack[#stack] + + if not escaped and first == "\\" and escapedChars[next] then + escaped = true + + elseif not escaped and first == context.delimiters.left then + table.insert(current.contents, {}) + stack[#stack + 1] = { start = position, contents = {} } + elseif not escaped and first == context.delimiters.right then + if #stack == 1 then + return nil, error("Delimiter " .. context.delimiters.right .. " never opened") + end + + -- we want special treatment for {} + saveUp(true) + + stack[#stack] = nil + elseif not escaped and first == context.separator and #stack > 1 then + -- we want to treat empty strings before , as empty strings + saveUp(false) + + current.contents = {} + else + local last = current.contents[#current.contents] + + if type(last) == "string" then + current.contents[#current.contents] = last .. first + else + table.insert(current.contents, first) + end + + escaped = false + end + + position = position + 1 + end + + if #stack > 1 then + return nil, error("Delimiter " .. context.delimiters.left .. " never closed", stack[2].start) + end + + return stack[1].contents, nil +end + +local context = { delimiters = { left = "{", right = "}" }, separator = "," } + +function M.abolishMany(many) + local total = 0 + + for _, entry in pairs(many) do + local left = parse(entry[1], context) + local right = parse(entry[2], context) + + local abbreviations = withCasing(M.betterAbolish(left, right)) + total = total + #abbreviations + + A.manyLocalAbbr(abbreviations) + end + + print("Added " .. total .. " abbreviations") +end + +-- function M.setup() +-- local context = { delimiters = { left = "{", right = "}" }, separator = "," } +-- print(vim.inspect({ parse("abc\\d{a, d,e}dsdf\\{sdf\\}", context) })) +-- local parsed, _ = parse("ab{e,{f0,1e,d2},f,{3,4,5},\\{{000,111}\\}}cd", context) +-- -- local parsed, _ = parse("abc", context) +-- print(vim.inspect(parsed)) +-- local processed = M.betterAbolish(parsed, parsed) +-- print(vim.inspect(processed)) +-- end + return M diff --git a/dotfiles/neovim/lua/my/plugins/init.lua b/dotfiles/neovim/lua/my/plugins/init.lua index cdd7a6b..54c6797 100644 --- a/dotfiles/neovim/lua/my/plugins/init.lua +++ b/dotfiles/neovim/lua/my/plugins/init.lua @@ -2,9 +2,12 @@ local env = require("my.helpers.env") local M = {} function M.setup() + require("my.plugins.moonwalk").setup() + require("my.plugins.chunk") require('nvim_comment').setup() require('fidget').setup() require('dressing').setup() + require('abbreinder').setup() require("my.plugins.autopairs").setup() require("my.plugins.telescope").setup() @@ -34,7 +37,8 @@ function M.setup() require("my.plugins.null-ls").setup() require("my.plugins.vimtex").setup() -- require("my.plugins.lean").setup() - -- require("my.plugins.notify").setup() + require("my.plugins.notify").setup() + require("my.plugins.iron").setup() end) if env.neovide.active() then @@ -55,6 +59,7 @@ function M.setup() require("my.plugins.hydra").setup() require("my.plugins.clipboard-image").setup() require("my.plugins.mind").setup() + require("my.plugins.ufo").setup() -- require("my.plugins.slam").setup() end diff --git a/dotfiles/neovim/lua/my/plugins/iron.lua b/dotfiles/neovim/lua/my/plugins/iron.lua new file mode 100644 index 0000000..0692811 --- /dev/null +++ b/dotfiles/neovim/lua/my/plugins/iron.lua @@ -0,0 +1,47 @@ +local M = {} + +function M.setup() + local iron = require("iron.core") + + iron.setup { + config = { + -- Your repl definitions come here + repl_definition = {}, + -- How the repl window will be displayed + -- See below for more information + repl_open_cmd = require('iron.view').right(40) + }, + -- Iron doesn't set keymaps by default anymore. + -- You can set them here or manually add keymaps to the functions in iron.core + keymaps = { + send_motion = "isc", + visual_send = "is", + send_file = "isf", + send_line = "isl", + send_mark = "ism", + mark_motion = "imc", + mark_visual = "imc", + remove_mark = "imd", + cr = "is", + interrupt = "is", + exit = "isq", + clear = "isr" + }, + -- If the highlight is on, you can change how it looks + -- For the available options, check nvim_set_hl + highlight = { italic = true }, + ignore_blank_lines = true -- ignore blank lines when sending visual select lines + } + + -- iron also has a list of commands, see :h iron-commands for all available commands + vim.keymap.set('n', 'iss', 'IronRepl') + vim.keymap.set('n', 'ir', 'IronRestart') + vim.keymap.set('n', 'if', 'IronFocus') + vim.keymap.set('n', 'ih', 'IronHide') + + local status, wk = pcall(require, "which-key") + + if status then wk.register({ ["i"] = { name = "Iron repl commands" } }) end +end + +return M diff --git a/dotfiles/neovim/lua/my/plugins/lspconfig.lua b/dotfiles/neovim/lua/my/plugins/lspconfig.lua index ad1fa8c..f799ad0 100644 --- a/dotfiles/neovim/lua/my/plugins/lspconfig.lua +++ b/dotfiles/neovim/lua/my/plugins/lspconfig.lua @@ -1,41 +1,68 @@ local M = {} function M.on_attach(client, bufnr) - -- Enable completion triggered by - vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') - - if client.server_capabilities.documentFormattingProvider then - vim.api.nvim_create_autocmd("BufWritePre", { - group = vim.api.nvim_create_augroup("LspFormatting", {}), - buffer = bufnr, - callback = function() - vim.lsp.buf.format({ async = false }) - end - }) + -- {{{ Auto format + local function format() + vim.lsp.buf.format({ async = false, bufnr = bufnr }) end + if false and client.supports_method("textDocument/formatting") then + vim.api.nvim_create_autocmd("BufWritePre", { + group = vim.api.nvim_create_augroup("LspFormatting", { clear = false }), + buffer = bufnr, + callback = format, + }) + end + -- }}} + -- {{{ Keymap helpers local opts = function(desc) return { noremap = true, silent = true, desc = desc } end - -- Go to declaration / definition / implementation - vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts("Go to declaration")) - vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts("Go to definition")) - vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts("Go to implementation")) - vim.keymap.set("n", "gr", vim.lsp.buf.references, opts("Go to references")) + local nmap = function(from, to, desc) + vim.keymap.set("n", from, to, opts(desc)) + end + -- }}} + -- {{{ Go to declaration / definition / implementation + nmap("gd", vim.lsp.buf.definition, "[G]o to [d]efinition") + nmap("gi", vim.lsp.buf.implementation, "[G]o to [i]mplementation") + nmap("gr", vim.lsp.buf.references, "[G]o to [r]eferences") + -- }}} + -- {{{ Hover + -- Note: diagnostics are already covered in keymaps.lua + nmap("K", vim.lsp.buf.hover, "Hover") + nmap("L", vim.lsp.buf.signature_help, "Signature help") + -- }}} + -- {{{ Code actions + nmap("rn", vim.lsp.buf.rename, "[R]e[n]ame") + nmap("f", format, "[F]ormat") + nmap("c", vim.lsp.buf.code_action, "[C]ode actions") - -- Hover - vim.keymap.set("n", "J", vim.diagnostic.open_float, opts("Show diagnostic")) - vim.keymap.set("n", "K", vim.lsp.buf.hover, opts("Hover")) - vim.keymap.set("n", "L", vim.lsp.buf.signature_help, opts("Signature help")) - - -- Code actions - vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts("Rename")) - vim.keymap.set("n", "c", vim.lsp.buf.code_action, opts("Code actions")) - vim.keymap.set("n", "f", vim.lsp.buf.format, opts("Format")) + vim.keymap.set( + "v", + "c", + ":'<,'> lua vim.lsp.buf.range_code_action()", + opts("[C]ode actions") + ) + -- }}} + -- {{{ Workspace stuff + nmap( + "wa", + vim.lsp.buf.add_workspace_folder, + "[W]orkspace [A]dd Folder" + ) + nmap( + "wr", + vim.lsp.buf.remove_workspace_folder, + "[W]orkspace [R]emove Folder" + ) + nmap("wl", function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, "[W]orkspace [L]ist Folders") + -- }}} end --- General server config +-- {{{ General server config ---@type lspconfig.options local servers = { tsserver = { @@ -43,39 +70,51 @@ local servers = { -- We handle formatting using null-ls and prettierd client.server_capabilities.documentFormattingProvider = false M.on_attach(client, bufnr) - end + end, }, dhall_lsp_server = {}, purescriptls = { settings = { purescript = { censorWarnings = { "UnusedName", "ShadowedName", "UserDefinedWarning" }, - formatter = "purs-tidy" - } - } + formatter = "purs-tidy", + }, + }, }, hls = { haskell = { -- set formatter - formattingProvider = "ormolu" - } + formattingProvider = "ormolu", + }, }, rnix = {}, cssls = {}, jsonls = {}, rust_analyzer = {}, + -- teal_ls = {}, sumneko_lua = { - cmd = { "lua-language-server", "--logpath=/home/adrielus/.local/share/lua-language-server/log" } - } + cmd = { + "lua-language-server", + "--logpath=/home/adrielus/.local/share/lua-language-server/log", + }, + }, } +-- }}} -M.capabilities = require('cmp_nvim_lsp').default_capabilities() +-- {{{ Capabilities +M.capabilities = require("cmp_nvim_lsp").default_capabilities() +-- Add folding capabilities +M.capabilities.textDocument.foldingRange = + { dynamicRegistration = false, lineFoldingOnly = true } +-- }}} function M.setup() - vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, - { border = "single" }) + -- {{{ Change on-hover borders + vim.lsp.handlers["textDocument/hover"] = + vim.lsp.with(vim.lsp.handlers.hover, { border = "single" }) vim.lsp.handlers["textDocument/signatureHelp"] = - vim.lsp.with(vim.lsp.handlers.signature_help, { border = "single" }) + vim.lsp.with(vim.lsp.handlers.signature_help, { border = "single" }) + -- }}} -- Setup basic language servers for lsp, details in pairs(servers) do @@ -84,15 +123,15 @@ function M.setup() details.on_attach = M.on_attach end - require('lspconfig')[lsp].setup { + require("lspconfig")[lsp].setup({ on_attach = details.on_attach, settings = details.settings, -- Specific per-language settings flags = { - debounce_text_changes = 150 -- This will be the default in neovim 0.7+ + debounce_text_changes = 150, -- This will be the default in neovim 0.7+ }, cmd = details.cmd, - capabilities = M.capabilities - } + capabilities = M.capabilities, + }) end end diff --git a/dotfiles/neovim/lua/my/plugins/moonwalk.lua b/dotfiles/neovim/lua/my/plugins/moonwalk.lua new file mode 100644 index 0000000..fb7bfae --- /dev/null +++ b/dotfiles/neovim/lua/my/plugins/moonwalk.lua @@ -0,0 +1,20 @@ +local M = {} + +function M.setup() + require("moonwalk").add_loader("tl", function(src, path) + local tl = require("tl") + local errs = {} + local _, program = tl.parse_program(tl.lex(src), errs) + + if #errs > 0 then + error( + path .. ":" .. errs[1].y .. ":" .. errs[1].x .. ": " .. errs[1].msg, + 0 + ) + end + + return tl.pretty_print_ast(program) + end) +end + +return M diff --git a/dotfiles/neovim/lua/my/plugins/neoconf.lua b/dotfiles/neovim/lua/my/plugins/neoconf.lua index 5e32a04..d60e604 100644 --- a/dotfiles/neovim/lua/my/plugins/neoconf.lua +++ b/dotfiles/neovim/lua/my/plugins/neoconf.lua @@ -2,7 +2,7 @@ local M = {} function M.setup() require("neoconf").setup({ - -- import existing settinsg from other plugins + -- import existing settings from other plugins import = { vscode = true, -- local .vscode/settings.json coc = false, -- global/local coc-settings.json diff --git a/dotfiles/neovim/lua/my/plugins/nerdtree.lua b/dotfiles/neovim/lua/my/plugins/nerdtree.lua index 5bcd3f2..5181b76 100644 --- a/dotfiles/neovim/lua/my/plugins/nerdtree.lua +++ b/dotfiles/neovim/lua/my/plugins/nerdtree.lua @@ -1,10 +1,8 @@ -local mapSilent = require("my.keymaps").mapSilent - local M = {} function M.setup() - -- Toggle nerdtree with Control-t - mapSilent("n", "", ":NERDTreeToggle") + -- Toggle nerdtree with Control-t + vim.keymaps.set("n", "", ":NERDTreeToggle", { silent = true }) end return M diff --git a/dotfiles/neovim/lua/my/plugins/notify.lua b/dotfiles/neovim/lua/my/plugins/notify.lua index 292485c..d5c84e0 100644 --- a/dotfiles/neovim/lua/my/plugins/notify.lua +++ b/dotfiles/neovim/lua/my/plugins/notify.lua @@ -1,7 +1,7 @@ local M = {} function M.setup() - vim.notify = require("notify") + -- vim.notify = require("notify") end return M diff --git a/dotfiles/neovim/lua/my/plugins/null-ls.lua b/dotfiles/neovim/lua/my/plugins/null-ls.lua index b63f7c4..19ebd4d 100644 --- a/dotfiles/neovim/lua/my/plugins/null-ls.lua +++ b/dotfiles/neovim/lua/my/plugins/null-ls.lua @@ -4,23 +4,20 @@ local M = {} function M.setup() local null_ls = require("null-ls") + -- require("refactoring").setup({}) local sources = { - -- null_ls.builtins.formatting.prettierd.with({extra_filetypes = {}}), -- format ts files - - null_ls.builtins.formatting.prettier.with({ extra_filetypes = {} }), -- format ts files - null_ls.builtins.formatting.lua_format.with({ - -- extra_args = function(params) - -- return params.options and params.options.tabSize and - -- { "--indent-width=" .. params.options.tabSize } - -- end - }) -- format lua code + -- null_ls.builtins.formatting.prettier.with({ extra_filetypes = {} }), -- format ts files + null_ls.builtins.formatting.prettierd.with({ extra_filetypes = {} }), -- format ts files + -- null_ls.builtins.formatting.lua_format.with({}), -- format lua code + null_ls.builtins.formatting.stylua.with({}), -- format lua code + -- null_ls.builtins.code_actions.refactoring.with({}), -- refactor stuff } null_ls.setup({ sources = sources, on_attach = lspconfig.on_attach, - debug = true + debug = true, }) end diff --git a/dotfiles/neovim/lua/my/plugins/ufo.lua b/dotfiles/neovim/lua/my/plugins/ufo.lua new file mode 100644 index 0000000..d067bd5 --- /dev/null +++ b/dotfiles/neovim/lua/my/plugins/ufo.lua @@ -0,0 +1,18 @@ +local M = {} + +function M.setup() + vim.o.foldcolumn = '0' + vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value + vim.o.foldlevelstart = 99 + vim.o.foldenable = true + + -- Using ufo provider need remap `zR` and `zM`. + -- vim.keymap.set('n', 'zR', require('ufo').openAllFolds) + -- vim.keymap.set('n', 'zM', require('ufo').closeAllFolds) + + -- Tell the server the capability of foldingRange, + -- Neovim hasn't added foldingRange to default capabilities, users must add it manually + -- require('ufo').setup() +end + +return M diff --git a/dotfiles/neovim/tl/my/plugins/chunk.tl b/dotfiles/neovim/tl/my/plugins/chunk.tl new file mode 100644 index 0000000..20b638e --- /dev/null +++ b/dotfiles/neovim/tl/my/plugins/chunk.tl @@ -0,0 +1,3 @@ +function hi() + print("Hello world!") +end diff --git a/dotfiles/vscode-snippets/snippets/lua/core.json b/dotfiles/vscode-snippets/snippets/lua/core.json index b14c2f6..ab3c56f 100644 --- a/dotfiles/vscode-snippets/snippets/lua/core.json +++ b/dotfiles/vscode-snippets/snippets/lua/core.json @@ -11,5 +11,23 @@ "", "return M" ] + }, + "Busted describe": { + "prefix": "describe", + "description": "Create a describe call for a busted test", + "body": [ + "describe(\"$1\", function ()", + "\t$0", + "end)" + ] + }, + "Busted it": { + "prefix": "it", + "description": "Create an it call for a busted test", + "body": [ + "it(\"$1\", function ()", + "\t$0", + "end)" + ] } } diff --git a/modules/applications/misc.nix b/modules/applications/misc.nix index 6e9758d..0003002 100644 --- a/modules/applications/misc.nix +++ b/modules/applications/misc.nix @@ -40,7 +40,6 @@ # vim # emacs vimclip # use neovim anywhere - neovide # neovim ui! # chat apps # slack diff --git a/modules/applications/neovim.nix b/modules/applications/neovim.nix index c9d35a8..5b2e60c 100644 --- a/modules/applications/neovim.nix +++ b/modules/applications/neovim.nix @@ -3,8 +3,22 @@ let paq = pkgs.fetchFromGitHub { owner = "savq"; repo = "paq-nvim"; - rev = "bc5950b990729464f2493b1eaab5a7721bd40bf5"; - sha256 = "0rsv3j5rxfv7ys9zvq775f63vy6w880b0xhyr164y8fcadhpypb3"; + rev = "0ed94d59e315e066ced3f453ff00c0ae94938f1e"; + sha256 = "0dsq6cjm7jm7jh9dfxym4ipkp46fvw1lr9z98zd80im18rg4fg63"; + }; + + teal = pkgs.fetchFromGitHub { + owner = "teal-language"; + repo = "tl"; + rev = "526fe3640fe6265706541c251e984c033a1a5ec9"; + sha256 = "0l31qj492iaiadpp4s0wflfb7vn6zzxwhbiyczisdgpd9ydj20gf"; + }; + + lazy-nvim = pkgs.fetchFromGitHub { + owner = "folke"; + repo = "lazy.nvim"; + rev = "511524ebff27ed8dea9e8d2eadb26ef19fb322c7"; + sha256 = "0c8hfhrj2rfkpff0kwiv5g5bpvdq36b4xzsi8199jrpfvvp79302"; }; theme = pkgs.myThemes.current; @@ -18,13 +32,14 @@ let haskell-language-server # haskell tectonic # also latex something? texlab # latex - # vscode-langservers-extracted # css and shit + nodePackages_latest.vscode-langservers-extracted # Formatters luaformatter # lua + stylua # lua ormolu # haskell easy-purescript-nix.purs-tidy - # prettierd # prettier but faster + nodePackages_latest.prettier_d_slim # Others nodePackages.typescript # typescript @@ -36,34 +51,41 @@ let libstdcxx5 # required by treesitter aparently zathura # pdf reader xdotool # for zathura reverse search or whatever it's called + lua # for repls and whatnot + glow # md preview in terminal + pandoc # md processing + libsForQt5.falkon # aparently needed for md preview + luajitPackages.luarocks # lua package manager texlive.combined.scheme-full # latex stuff python38Packages.pygments # required for latex syntax highlighting ]; - base = pkgs.neovim-nightly; - # base = pkgs.neovim; - - neovim = + wrapClient = { base, name }: pkgs.symlinkJoin { inherit (base) name meta; paths = [ base ]; nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' - wrapProgram $out/bin/nvim \ - --prefix PATH : ${lib.makeBinPath extraPackages} + wrapProgram $out/bin/${name} \ + --prefix PATH : ${lib.makeBinPath extraPackages} \ + --set LAZY_NVIM_PATH ${lazy-nvim} ''; }; + neovim = wrapClient { base = pkgs.neovim-nightly; name = "nvim"; }; + neovide = wrapClient { base = pkgs.neovide; name = "neovide"; }; + nixPlugins = ".local/share/nvim/site/pack/nix"; in { home-manager.users.adrielus = { config, ... }: let simlink = config.lib.file.mkOutOfStoreSymlink; in { - home.file.".local/share/nvim/site/pack/paqs/start/paq-nvim".source = paq; + home.file."${nixPlugins}/start/paq-nvim".source = paq; home.file."${nixPlugins}/start/theming/lua/my/theme.lua".source = theme.neovim.theme; + home.file."${nixPlugins}/start/teal/lua".source = teal; # teal (typed lua) home.file."${nixPlugins}/start/snippets".source = simlink "${paths.dotfiles}/vscode-snippets"; home.file.".config/nvim".source = simlink "${paths.dotfiles}/neovim"; @@ -71,6 +93,7 @@ in home.packages = [ neovim + neovide ]; }; } diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..03d2f90 --- /dev/null +++ b/stylua.toml @@ -0,0 +1,3 @@ +column_width = 80 +indent_width = 2 +indent_type = "Spaces"