diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-05-04 08:44:50 +0200 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-05-06 16:43:16 +0200 |
| commit | 34510ebc63ff65d51f6979a86169bfc52de6180c (patch) | |
| tree | 36c8b73c99a3c566ccee888818c60204398991fd /plugin | |
| download | nvim-config-34510ebc63ff65d51f6979a86169bfc52de6180c.tar.gz nvim-config-34510ebc63ff65d51f6979a86169bfc52de6180c.zip | |
feat: initial setup
- `dotfiles` (this project's CLI)
- foot configuration
- tmux configuration
- bash configuration
- nvim (as a git submodule) + configuration
- ranger configuration
- fzf configuration
- KDE global shortcuts
- Other miscellaneous dependencies
Diffstat (limited to 'plugin')
| -rw-r--r-- | plugin/10-treesitter.lua | 37 | ||||
| -rw-r--r-- | plugin/50-autoformat.lua | 24 | ||||
| -rw-r--r-- | plugin/50-autopairs.lua | 17 | ||||
| -rw-r--r-- | plugin/50-colors.lua | 99 | ||||
| -rw-r--r-- | plugin/50-completion.lua | 72 | ||||
| -rw-r--r-- | plugin/50-dap.lua | 28 | ||||
| -rw-r--r-- | plugin/50-dotfiles.lua | 36 | ||||
| -rw-r--r-- | plugin/50-fold.lua | 22 | ||||
| -rw-r--r-- | plugin/50-ftdetect.lua | 18 | ||||
| -rw-r--r-- | plugin/50-highlight.lua | 101 | ||||
| -rw-r--r-- | plugin/50-local.lua | 8 | ||||
| -rw-r--r-- | plugin/50-lorem.lua | 35 | ||||
| -rw-r--r-- | plugin/50-lsp.lua | 90 | ||||
| -rw-r--r-- | plugin/50-netrw.lua | 25 | ||||
| -rw-r--r-- | plugin/50-session.lua | 69 | ||||
| -rw-r--r-- | plugin/50-spell.lua | 34 | ||||
| -rw-r--r-- | plugin/50-statusline.lua | 48 |
17 files changed, 763 insertions, 0 deletions
diff --git a/plugin/10-treesitter.lua b/plugin/10-treesitter.lua new file mode 100644 index 0000000..4602519 --- /dev/null +++ b/plugin/10-treesitter.lua @@ -0,0 +1,37 @@ +-- +-- Treesitter parsers +-- + +vim.pack.add({ "https://github.com/nvim-treesitter/nvim-treesitter" }) + +require("nvim-treesitter").install({ + "bash", + "diff", + "gitcommit", + "ini", + "json", + "lua", + "markdown", + "markdown_inline", + "readline", + "vim", + "vimdoc", +}) + +-- Parse the tree as early as possible, which is as soon as we know the filetype +-- +-- Event handlers for the same event are triggered in the order they were created. This must be the first FileType +-- handler created so that the tree is parsed for other FileType handlers (which often need the parsed tree). To create +-- it first put this in a file that comes before alphabetically in the `plugin/` directory. +vim.api.nvim_create_autocmd("FileType", { + desc = "Start treesitter", + group = vim.g.dotfiles.augroup, + callback = function() + local parser = vim.treesitter.get_parser(0) + if parser == nil then + return + end + parser:parse() -- Parse once asynchronously; used by logic that needs the parsed tree (like extmarks) + vim.treesitter.start() + end, +}) diff --git a/plugin/50-autoformat.lua b/plugin/50-autoformat.lua new file mode 100644 index 0000000..4761097 --- /dev/null +++ b/plugin/50-autoformat.lua @@ -0,0 +1,24 @@ +-- +-- Autoformat plugin +-- + +local function toggle_autoformat() + vim.b.autoformat = not vim.b.autoformat +end + +-- Autoformat +vim.api.nvim_create_autocmd("BufWritePre", { + desc = "Autoformat buffer", + group = vim.g.dotfiles.augroup, + callback = function(ev) + if vim.b.autoformat then + if vim.b.format_func == nil then + vim.notify("No formatter set for " .. ev.file .. " (" .. vim.o.filetype .. ")", vim.log.levels.WARN) + return + end + vim.b.format_func() + end + end, +}) + +vim.api.nvim_create_user_command("AutoformatToggle", toggle_autoformat, { desc = "Toggle autoformatting" }) diff --git a/plugin/50-autopairs.lua b/plugin/50-autopairs.lua new file mode 100644 index 0000000..2ab41c8 --- /dev/null +++ b/plugin/50-autopairs.lua @@ -0,0 +1,17 @@ +-- +-- Autopairs configuration (inserting matching delimiters while inserting) +-- +-- See https://github.com/windwp/nvim-autopairs + +vim.pack.add({ "https://github.com/windwp/nvim-autopairs" }) + +local Rule = require("nvim-autopairs.rule") +local npairs = require("nvim-autopairs") +local cond = require("nvim-autopairs.conds") + +npairs.setup() + +npairs.add_rules({ + Rule("*", "*", "markdown"):with_cr(cond.none()), + Rule("~", "~", "markdown"):with_cr(cond.none()), +}) diff --git a/plugin/50-colors.lua b/plugin/50-colors.lua new file mode 100644 index 0000000..f713a74 --- /dev/null +++ b/plugin/50-colors.lua @@ -0,0 +1,99 @@ +-- +-- Color scheme plugin +-- +vim.pack.add({ "https://github.com/maxmx03/solarized.nvim" }) -- Solarized color scheme + +local solarized_colors = { + base03 = "#002b36", + base02 = "#073642", + base01 = "#586e75", + base00 = "#657b83", + base0 = "#839496", + base1 = "#93a1a1", + base2 = "#eee8d5", + base3 = "#fdf6e3", + yellow = "#b58900", + orange = "#cb4b16", + red = "#dc322f", + magenta = "#d33682", + violet = "#6c71c4", + blue = "#268bd2", + cyan = "#2aa198", + green = "#859900", +} + +local function adjust_highlight() + if vim.g.colors_name == "solarized" then + -- General highlight + vim.api.nvim_set_hl(0, "EndOfBuffer", { fg = solarized_colors.base0, update = true }) + vim.api.nvim_set_hl(0, "MatchParen", { link = "CurSearch" }) + if vim.o.background == "light" then + vim.api.nvim_set_hl(0, "TabLineSel", { bg = "#edffd5" }) + vim.api.nvim_set_hl(0, "Cursorline", { bg = "#edffd5" }) + vim.api.nvim_set_hl(0, "NormalFloat", { bg = solarized_colors.base2 }) + elseif vim.o.background == "dark" then + vim.api.nvim_set_hl(0, "TabLineSel", { bg = "#043624" }) + vim.api.nvim_set_hl(0, "Cursorline", { bg = "#043624" }) + vim.api.nvim_set_hl(0, "NormalFloat", { bg = solarized_colors.base02 }) + end + + -- Markdown highlight + if vim.o.background == "light" then + vim.api.nvim_set_hl(0, "@markup.raw", { bg = solarized_colors.base2, update = true }) + elseif vim.o.background == "dark" then + vim.api.nvim_set_hl(0, "@markup.raw", { bg = solarized_colors.base02, update = true }) + end + vim.api.nvim_set_hl(0, "@markup.raw.block", { fg = solarized_colors.cyan, update = true }) + vim.api.nvim_set_hl(0, "@markup.heading.1", { link = "@markup.heading" }) + vim.api.nvim_set_hl(0, "@markup.heading.2", { link = "@markup.heading" }) + vim.api.nvim_set_hl(0, "@markup.heading.3", { link = "@markup.heading" }) + vim.api.nvim_set_hl(0, "@markup.heading.4", { link = "@markup.heading" }) + vim.api.nvim_set_hl(0, "@markup.heading.5", { link = "@markup.heading" }) + vim.api.nvim_set_hl(0, "@markup.heading.6", { link = "@markup.heading" }) + end +end + +local function next_colorscheme() + local colorschemes = vim.fn.getcompletion("", "color") + vim.g.colors_name = vim.g.colors_name or "default" + for i = 1, #colorschemes do + if colorschemes[i] == vim.g.colors_name then + vim.cmd.colorscheme(colorschemes[(i % #colorschemes) + 1]) + vim.notify("Color scheme set to " .. vim.g.colors_name) + return + end + end +end + +local function random_colorscheme() + local colorschemes = vim.fn.getcompletion("", "color") + vim.cmd.colorscheme(colorschemes[math.random(#colorschemes)]) + vim.notify("Color scheme set to " .. vim.g.colors_name) +end + +local function toggle_theme() + vim.opt.background = vim.o.background == "light" and "dark" or "light" + vim.notify("Color theme set to " .. vim.o.background) +end + +-- Adjust colors after the color scheme has loaded +vim.api.nvim_create_autocmd("ColorScheme", { + desc = "Adjust color scheme", + group = vim.g.dotfiles.augroup, + callback = adjust_highlight, +}) + +-- Adjust colors when the theme (light/dark) changes +vim.api.nvim_create_autocmd("OptionSet", { + desc = "Adjust color scheme", + pattern = "background", + group = vim.g.dotfiles.augroup, + callback = adjust_highlight, +}) + +vim.cmd.colorscheme("solarized") -- Default colorscheme +vim.opt.background = "dark" -- Default theme + +vim.api.nvim_create_user_command("ColorsNext", next_colorscheme, { desc = "Load next color scheme" }) +vim.api.nvim_create_user_command("ColorsRandom", random_colorscheme, { desc = "Load random color scheme" }) +vim.api.nvim_create_user_command("ColorsThemeToggle", toggle_theme, { desc = "Toggle light/dark theme" }) diff --git a/plugin/50-completion.lua b/plugin/50-completion.lua new file mode 100644 index 0000000..94b4cbb --- /dev/null +++ b/plugin/50-completion.lua @@ -0,0 +1,72 @@ +-- +-- Completion configuration plugin +-- + +------------------------------------------------------------------------------------------------------------------------ +-- Insert mode completion +------------------------------------------------------------------------------------------------------------------------ +-- See `:help ins-completion-menu` + +vim.opt.autocomplete = true -- Show completion menu automatically +vim.opt.completeopt = { + "noselect", -- No item selected initially + "fuzzy", + "menuone", -- Show matches in a menu, even if there's only one match + "popup", -- Menu items show extra ingo in the popup window + "preview", -- Show extra info in the preview window +} +-- Completion sources (in order of priority) +vim.opt.complete = { + "o", -- 'omnifunc' +} +vim.opt.pumwidth = 25 +vim.keymap.set("i", "<Tab>", function() + return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>" +end, { expr = true }) +vim.keymap.set("i", "<S-Tab>", function() + return vim.fn.pumvisible() == 1 and "<C-p>" or "<S-Tab>" +end, { expr = true }) + +------------------------------------------------------------------------------------------------------------------------ +-- Command-line mode completion +------------------------------------------------------------------------------------------------------------------------ +-- See `:help cmdline-completion` and `:help cmdline-autocompletion` + +-- Show completion menu automatically +vim.api.nvim_create_autocmd({ "CmdlineChanged", "CmdlineEnter" }, { + desc = "Autocompletion", + group = vim.g.dotfiles.augroup, + pattern = "[:\\/\\?]", + callback = function() + vim.cmd.call("wildtrigger()") + end, +}) +vim.opt.wildmenu = true -- Show completions in a menu +vim.opt.wildchar = 9 -- Char code assigned to command line wildcard expansion +vim.opt.wildoptions = { + "exacttext", -- Discard regex artifacts when performing search pattern completion + "pum", -- Show completions in a popup menu + "tagfile", -- Show tag kind and file + "fuzzy", -- Fuzzy matching (doesn't work with files/dirs, see `:help 'wildoptions'`, but patterns do work!) +} +-- Completion modes triggered in order by `wildtrigger()` or 'wildchar' +vim.opt.wildmode = { + "noselect", -- List matches without inserting + "full", -- List matches and insert first full match +} +-- Insert unique match +vim.keymap.set("c", string.format("%c", vim.o.wildchar), function() + local complete_info = vim.fn.cmdcomplete_info() + if complete_info.pum_visible == 1 then + return #complete_info.matches == 1 and "<C-n><Space><BS>" or "<C-n>" + end + vim.fn.wildtrigger() +end, { expr = true, desc = "Command line wildcard expansion" }) +-- Show next completion choices after accepting an entry with `<C-y>` +vim.keymap.set("c", "<C-y>", function() + local complete_info = vim.fn.cmdcomplete_info() + if complete_info.pum_visible == 1 then + return complete_info.selected ~= -1 and "<Space><BS>" or "<C-e>" + end + return "<C-y>" +end, { expr = true }) diff --git a/plugin/50-dap.lua b/plugin/50-dap.lua new file mode 100644 index 0000000..683984c --- /dev/null +++ b/plugin/50-dap.lua @@ -0,0 +1,28 @@ +-- +-- DAP client/adapter configurations +-- + +vim.pack.add({ "https://github.com/mfussenegger/nvim-dap" }) -- DAP (Debug Adapter Protocol) client +local dap = require("dap") + +-- OSV configuration +vim.pack.add({ "https://github.com/jbyuki/one-small-step-for-vimkind" }) -- DAP adapter for Neovim Lua +local osv = require("osv") + +dap.configurations.lua = { + { + type = "nlua", + request = "attach", + name = "Attach to running Neovim instance", + }, +} +dap.adapters.nlua = function(callback, config) + callback({ type = "server", host = config.host or "127.0.0.1", port = config.port or 8086 }) +end +vim.api.nvim_create_user_command("OSVLaunch", function() + osv.launch({ port = 8086 }) +end, { desc = "Launch OSV server" }) +vim.api.nvim_create_user_command("OSVStatus", function() + vim.notify("OSV server running: " .. tostring(osv.is_running())) + vim.notify("OSV client attached: " .. tostring(osv.is_attached())) +end, { desc = "Show OSV status" }) diff --git a/plugin/50-dotfiles.lua b/plugin/50-dotfiles.lua new file mode 100644 index 0000000..122912c --- /dev/null +++ b/plugin/50-dotfiles.lua @@ -0,0 +1,36 @@ +-- +-- dotfiles plugin +-- + +-- Returns true if the current buffer is part of the Dotfiles repository +local function detect_dotfiles_file() + if vim.env.DOTFILES_DIR == nil then + return false + end + local ret = vim.system( + { "git", "--git-dir=" .. vim.env.DOTFILES_DIR, "--work-tree=" .. vim.env.HOME, "ls-files" }, + { text = true } + ):wait() + local buf_file_name = string.sub(vim.api.nvim_buf_get_name(0), #vim.env.HOME + 2) + for _, dotfiles_filename in ipairs(vim.split(ret.stdout, "\n", { trimempty = true })) do + if dotfiles_filename == buf_file_name then + return true + end + end + return false +end + +vim.api.nvim_create_autocmd("BufEnter", { + desc = "Detect dotfiles file", + group = vim.g.dotfiles.augroup, + callback = function() + vim.b.dotfiles_file = detect_dotfiles_file() + end, +}) + +vim.api.nvim_create_user_command("DotfilesOn", function() + vim.g.gitgutter_git_args = "--git-dir=" .. vim.env.DOTFILES_DIR .. " --work-tree=" .. vim.env.HOME +end, { desc = "Activate dotfiles (set git env)" }) +vim.api.nvim_create_user_command("DotfilesOff", function() + vim.g.gitgutter_git_args = "" +end, { desc = "Deactivate dotfiles (unset git env)" }) diff --git a/plugin/50-fold.lua b/plugin/50-fold.lua new file mode 100644 index 0000000..c7013bb --- /dev/null +++ b/plugin/50-fold.lua @@ -0,0 +1,22 @@ +-- +-- fold plugin +-- + +-- Initialize folds with foldmethod = expr if a treesitter parser is available, then switch back to manual +-- This is to have the folds calculated and closed when editing the file initially, but with foldmethod set to manual +-- Without foldmethod set to manual folds are created while writing in insert mode which is annoying +-- +-- Skip floating windows, because they often are documentation (and thus should be visible by default) +vim.api.nvim_create_autocmd("FileType", { + desc = "Initialize folds", + group = vim.g.dotfiles.augroup, + callback = function(ev) + if vim.api.nvim_win_get_config(0).relative ~= "" or vim.treesitter.get_parser(0) == nil then + return + end + vim.opt_local.foldexpr = "v:lua.vim.treesitter.foldexpr()" + vim.opt_local.foldmethod = "expr" + vim.cmd.normal({ "zX", bang = true }) + vim.opt_local.foldmethod = "manual" + end, +}) diff --git a/plugin/50-ftdetect.lua b/plugin/50-ftdetect.lua new file mode 100644 index 0000000..49fc6d6 --- /dev/null +++ b/plugin/50-ftdetect.lua @@ -0,0 +1,18 @@ +-- +-- Filetype detection plugin +-- + +-- Detect bash files +vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, { + desc = "Detect bash file", + group = vim.g.dotfiles.augroup, + pattern = "*", + callback = function() + if + string.find(vim.api.nvim_buf_get_name(0), "%.bash$") + or string.find(vim.api.nvim_buf_get_lines(0, 0, 1, false)[1] or "", "^#!/usr/bin/bash") + then + vim.bo.filetype = "bash" + end + end, +}) diff --git a/plugin/50-highlight.lua b/plugin/50-highlight.lua new file mode 100644 index 0000000..0e8fb97 --- /dev/null +++ b/plugin/50-highlight.lua @@ -0,0 +1,101 @@ +-- +-- Custom highlighting plugin (in `after/` to that the autocommand in `treesitter/init.lua` can be set first in order) +-- + +-- Returns an iterator over the ascendants of `node`, starting at the root node +local function node_ascendants(node) + local root = node:tree():root() + local current = root + return function() + if current:equal(node) then + return nil + end + current = assert(current:child_with_descendant(node)) + return current + end +end + +-- Returns true if `node` or any of its parent has the type `type` +local function node_within_type(node, type) + local next_ascendant = node_ascendants(node) + local next = next_ascendant() + while next do + if next:type() == type then + return true + end + next = next_ascendant() + end + return false +end + +-- Returns an iterator over the positions (`{ col1, col2, row }`) of matches of pattern in lines +local function pmatches(lines, pattern) + local col1, col2, row = nil, nil, 1 + return function() + while row < #lines do + col1, col2 = string.find(lines[row], pattern, (col2 or 0) + 1) + if col1 then + return { col1 = col1, col2 = col2, row = row } + else + col1, col2, row = 0, 0, row + 1 + end + end + return nil + end +end + +-- Set extmarks are the positions (`{ col1, col2, row }`) given by `next_pos()` +-- `opts`: { +-- ns: highlight namespace +-- predicate: is passed row and col, if true then set the mark +-- hl_group: highlight group +-- } +local function set_extmarks(next_pos, opts) + for pos in next_pos do + local marks = vim.api.nvim_buf_get_extmarks( + 0, + opts.ns, + { pos.row - 1, pos.col1 - 1 }, + { pos.row - 1, pos.col2 - 1 }, + {} + ) + if #marks == 0 and opts.predicate(pos.row - 1, pos.col1 - 1) then + vim.api.nvim_buf_set_extmark( + 0, + opts.ns, + pos.row - 1, + pos.col1 - 1, + { end_col = pos.col2, hl_group = opts.hl_group } + ) + end + pos = next_pos() + end +end + +-- TODO a better way to do this: +-- For code, only check in "comment" node ranges +-- For non-code, do it per type. For Markdown, only check "paragraph" nodes +local function hl_todo_predicate(row, col) + if vim.o.filetype == "markdown" or vim.treesitter.get_parser() == nil then + return true + end + local node = assert(vim.treesitter.get_node({ pos = { row, col } })) + return node_within_type(node, "comment") +end + +local patterns = { todo = "TODO" } +local hl_ns = vim.api.nvim_create_namespace("extmarks") + +vim.api.nvim_set_hl(hl_ns, "dotfiles.Todo", { bg = "Yellow", fg = "Black", bold = true }) +local extmarks_todo_opts = { ns = hl_ns, hl_group = "dotfiles.Todo", predicate = hl_todo_predicate } + +-- Initialize extmarks +vim.api.nvim_create_autocmd("FileType", { + desc = "Initialize extmarks", + group = vim.g.dotfiles.augroup, + callback = function() + vim.api.nvim_win_set_hl_ns(vim.api.nvim_get_current_win(), hl_ns) + local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) + set_extmarks(pmatches(lines, patterns.todo), extmarks_todo_opts) + end, +}) diff --git a/plugin/50-local.lua b/plugin/50-local.lua new file mode 100644 index 0000000..88c63c5 --- /dev/null +++ b/plugin/50-local.lua @@ -0,0 +1,8 @@ +-- +-- local include plugin +-- + +local local_config_file = vim.fn.stdpath("config") .. "/local.lua" +if vim.uv.fs_stat(local_config_file) then + dofile(local_config_file) +end diff --git a/plugin/50-lorem.lua b/plugin/50-lorem.lua new file mode 100644 index 0000000..8970574 --- /dev/null +++ b/plugin/50-lorem.lua @@ -0,0 +1,35 @@ +-- +-- Lorem plugin (command to insert "lorem ipsum" words) +-- + +-- Returns lorem ipsum words +local function iter_lorem() + local filename = vim.env.HOME .. "/.local/share/dotfiles/lorem.txt" + local file = assert(io.open(filename, "r")) + local string = file:read("*all") + io.close(file) + local lorem_words = vim.split(vim.trim(string), " ", { trimempty = true }) + local i = 0 + return function() + i = i % #lorem_words + 1 + return lorem_words[i] + end +end + +-- Returns a n words long "lorem ipsum" string +local function get_lorem(n) + local iter = iter_lorem() + local words = {} + for i = 1, n do + words[i] = iter() + end + return table.concat(words, " ") +end + +local function put_lorem(n) + vim.api.nvim_put({ get_lorem(n) }, "c", true, true) +end + +vim.api.nvim_create_user_command("Lorem", function(opts) + put_lorem(tonumber(opts.args)) +end, { desc = "Put lorem ipsum string", nargs = 1 }) diff --git a/plugin/50-lsp.lua b/plugin/50-lsp.lua new file mode 100644 index 0000000..de86ecd --- /dev/null +++ b/plugin/50-lsp.lua @@ -0,0 +1,90 @@ +-- +-- LSP client configurations +-- + +local function inspect_lsp() + local client = vim.lsp.get_clients()[1] + if client == nil then + vim.notify("No LSP client loaded") + return + end + vim.notify(vim.inspect(client.server_capabilities), vim.log.levels.INFO) +end + +vim.pack.add({ "https://github.com/neovim/nvim-lspconfig" }) + +vim.api.nvim_create_user_command("LspInspect", inspect_lsp, { desc = "Inpsect LSP client" }) + +-- Enable LSP server capabilities if available when attaching, see `:help lsp-attach` +vim.api.nvim_create_autocmd("LspAttach", { + desc = "Enable LSP capabilities", + group = vim.g.dotfiles.augroup, + callback = function(ev) + local client = assert(vim.lsp.get_client_by_id(ev.data.client_id)) + if client:supports_method("textDocument/completion") then + vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true }) + else + vim.notify("Client " .. client.name .. " does not support completion", vim.log.levels.WARN) + end + if client:supports_method("textDocument/inlayHint") then + vim.lsp.inlay_hint.enable(true, { bufnr = 0 }) + else + vim.notify("Client " .. client.name .. " does not support inlay hints", vim.log.levels.WARN) + end + end, +}) + +vim.api.nvim_create_user_command("LspHintToggle", function() + vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = 0 }), { bufnr = 0 }) +end, { desc = "Toggle LSP inlay hints" }) + +------------------------------------------------------------------------------------------------------------------------ +-- Lua +------------------------------------------------------------------------------------------------------------------------ + +vim.lsp.config("lua_ls", { + on_init = function(client) + -- Use `.luarc.json` or `.luarc.jsonc` if available, then exit + -- See `:help vim.lsp.ClientConfig` for `workspace_folders` + if client.workspace_folders then + local path = client.workspace_folders[1].name + if + path ~= vim.fn.stdpath("config") + and (vim.uv.fs_stat(path .. "/.luarc.json") or vim.uv.fs_stat(path .. "/.luarc.jsonc")) + then + return + end + end + -- See Lua language server configuration settings at https://luals.github.io/wiki/settings + client.config.settings.Lua = vim.tbl_deep_extend("force", client.config.settings.Lua, { + runtime = { + version = "Lua 5.1", + path = { "?.lua", "?/init.lua" }, -- See `:h lua-module-load` + }, + workspace = { + checkThirdParty = false, + library = vim.api.nvim_get_runtime_file("", true), -- Load all folders in 'runtimepath' + }, + }) + end, +}) +vim.lsp.enable("lua_ls") + +------------------------------------------------------------------------------------------------------------------------ +-- Bash +------------------------------------------------------------------------------------------------------------------------ + +vim.lsp.enable("bashls") + +------------------------------------------------------------------------------------------------------------------------ +-- Markdown +------------------------------------------------------------------------------------------------------------------------ + +vim.lsp.config("marksman", { filetypes = { "markdown" } }) +vim.lsp.enable("marksman") + +------------------------------------------------------------------------------------------------------------------------ +-- Vimscript +------------------------------------------------------------------------------------------------------------------------ + +vim.lsp.enable("vimls") diff --git a/plugin/50-netrw.lua b/plugin/50-netrw.lua new file mode 100644 index 0000000..4fdbfa6 --- /dev/null +++ b/plugin/50-netrw.lua @@ -0,0 +1,25 @@ +-- +-- netrw plugin +-- + +local function explore() + local windows = vim.api.nvim_tabpage_list_wins(0) + for _, win in ipairs(windows) do + local buf = vim.api.nvim_win_get_buf(win) + local ft = vim.api.nvim_get_option_value("filetype", { buf = buf }) + if ft == "netrw" then + if win ~= vim.api.nvim_get_current_win() then + vim.api.nvim_set_current_win(win) + return + end + break + end + end + vim.cmd.Lexplore() +end + +vim.g.netrw_liststyle = 3 -- 3: list style +vim.g.netrw_winsize = -30 -- 30 colums wide +vim.g.netrw_banner = 0 -- No banner + +vim.api.nvim_create_user_command("GotoExplorer", explore, { desc = "Open/close/focus netrw window" }) diff --git a/plugin/50-session.lua b/plugin/50-session.lua new file mode 100644 index 0000000..b4aadda --- /dev/null +++ b/plugin/50-session.lua @@ -0,0 +1,69 @@ +-- +-- Session plugin +-- + +local session_dir = vim.fn.stdpath("state") .. "/sessions" +local session_default = session_dir .. "/default.vim" +if not vim.uv.fs_stat(session_dir) then + vim.uv.fs_mkdir(session_dir, tonumber("755", 8)) + vim.notify("Sessions save directory created at " .. session_dir) +end + +local function save_session(path) + vim.cmd.mksession({ path, bang = true }) +end + +local function load_session(path) + vim.cmd.source(path) +end + +local function reload_session(path) + save_session(path) + vim.cmd.restart({ args = { "+qall", "SessionLoad", path } }) +end + +local function delete_session(path) + vim.fs.rm(path) +end + +local function session_completefunc(arg_lead, _, _) + local completions = {} + for path in vim.fs.dir(session_dir) do + if string.match(path, "^" .. arg_lead) and string.match(path, ".vim$") then + completions[#completions + 1] = path:sub(1, -5) + end + end + return completions +end + +local function session_op(base, op) + local path = #base > 0 and base or session_default + if not string.match(path, "^" .. session_dir) then + path = session_dir .. "/" .. path + end + if not string.match(path, "%.vim$") then + path = path .. ".vim" + end + op(path) +end + +vim.api.nvim_create_user_command("SessionSave", function(ev) + session_op(ev.args, save_session) +end, { desc = "Save session", nargs = "?", complete = session_completefunc }) +vim.api.nvim_create_user_command("SessionLoad", function(ev) + session_op(ev.args, load_session) +end, { desc = "Load session", nargs = "?", complete = session_completefunc }) +vim.api.nvim_create_user_command("SessionDelete", function(ev) + session_op(ev.args, delete_session) +end, { desc = "Delete session", nargs = "?", complete = session_completefunc }) +vim.api.nvim_create_user_command("SessionRestart", function(ev) + session_op(ev.args, reload_session) +end, { desc = "Reload session", nargs = "?", complete = session_completefunc }) +vim.api.nvim_create_user_command("SessionExitSave", function(ev) + session_op(ev.args, save_session) + vim.cmd.qall() +end, { desc = "Save and exit session", nargs = "?", complete = session_completefunc }) +vim.api.nvim_create_user_command("SessionExitNoSave", function(ev) + session_op(ev.args, save_session) + vim.cmd.qall({ bang = true }) +end, { desc = "Save and exit session", nargs = "?", complete = session_completefunc }) diff --git a/plugin/50-spell.lua b/plugin/50-spell.lua new file mode 100644 index 0000000..56d4c5f --- /dev/null +++ b/plugin/50-spell.lua @@ -0,0 +1,34 @@ +-- +-- Spell check plugin +-- + +local function toggle_spell() + vim.o.spell = not vim.o.spell +end + +local function set_spell_en() + vim.opt.spelllang = { "en_us" } +end + +local function set_spell_fr() + vim.opt.spelllang = { "fr" } +end + +local function set_spell_en_fr() + vim.opt.spelllang = { "en_us", "fr" } +end + +vim.opt.spelllang = "en_us" -- Initial spell language +vim.opt.spellfile = { -- Spellfiles for zg, zw, z=, etc + "/home/tvanbesi/.config/nvim/spell/en.utf-8.add", + "/home/tvanbesi/.config/nvim/spell/fr.utf-8.add", +} + +vim.api.nvim_create_user_command("SpellToggle", toggle_spell, { desc = "Toggle spell checking" }) +vim.api.nvim_create_user_command("SpellSetEn", set_spell_en, { desc = "Set spell language to English" }) +vim.api.nvim_create_user_command("SpellSetFr", set_spell_fr, { desc = "Set spell language to French" }) +vim.api.nvim_create_user_command( + "SpellSetEnFr", + set_spell_en_fr, + { desc = "Set spell languages to English and French" } +) diff --git a/plugin/50-statusline.lua b/plugin/50-statusline.lua new file mode 100644 index 0000000..092f08f --- /dev/null +++ b/plugin/50-statusline.lua @@ -0,0 +1,48 @@ +-- +-- Status line configuration plugin +-- +-- I use lualine, see https://github.com/nvim-lualine/lualine.nvim#configuring-lualine-in-initvim + +vim.pack.add({ + "https://github.com/nvim-tree/nvim-web-devicons", + "https://github.com/nvim-lualine/lualine.nvim", +}) +local lualine = require("lualine") + +local function spell_status() + if vim.o.spelllang == "fr" then + return "+S(fr)" + elseif vim.o.spelllang == "en_us" then + return "+S(en)" + elseif vim.o.spelllang == "en_us,fr" then + return "+S(en,fr)" + end +end + +local function statuses() + return (vim.b.autoformat and "+F" or "") .. (vim.o.spell and spell_status() or "") +end + +local lualine_sections = { + lualine_c = { statuses, "filename" }, + lualine_x = { "encoding", "fileformat", "filetype", "lsp_status" }, +} + +-- Adjust colors when the theme (light/dark) changes +vim.api.nvim_create_autocmd("OptionSet", { + desc = "Adjust color scheme", + pattern = "background", + group = vim.g.dotfiles.augroup, + callback = function() + lualine.setup({ + options = { theme = vim.o.background == "light" and "solarized_light" or "solarized_dark" }, + sections = lualine_sections, + }) + end, +}) + +lualine.setup({ options = { theme = "solarized_light" }, sections = lualine_sections }) + +vim.api.nvim_create_user_command("LualineConfig", function() + vim.notify(vim.inspect(lualine.get_config())) +end, { desc = "Show lualine configuration" }) |
