├── lua ├── setup │ ├── mini-ai.lua │ ├── mini-pairs.lua │ ├── autopairs.lua │ ├── mini-bracketed.lua │ ├── mini-bufremove.lua │ ├── mini-surround.lua │ ├── themes │ │ ├── zenbones.lua │ │ ├── nightfox.lua │ │ ├── kanagawa.lua │ │ └── catppuccin.lua │ ├── notify.lua │ ├── auto-session.lua │ ├── kb.lua │ ├── highlight-colors.lua │ ├── pounce.lua │ ├── mini-indentscope.lua │ ├── gitsigns.lua │ ├── comment.lua │ ├── spelling.lua │ ├── oil.lua │ ├── zen-mode.lua │ ├── mini-move.lua │ ├── qmk.lua │ ├── which-key.lua │ ├── navbuddy.lua │ ├── treesitter.lua │ ├── blink.lua │ ├── conform.lua │ ├── fzf.lua │ ├── snacks.lua │ ├── telescope.lua │ ├── lsp.lua │ └── lualine.lua ├── lazySetup.lua ├── options.lua └── mappings.lua ├── .gitignore ├── filetype.lua ├── README.md └── init.lua /lua/setup/mini-ai.lua: -------------------------------------------------------------------------------- 1 | require("mini.ai").setup() 2 | -------------------------------------------------------------------------------- /lua/setup/mini-pairs.lua: -------------------------------------------------------------------------------- 1 | require("mini.pairs").setup() 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /undo 2 | .repro 3 | .DS_Store 4 | lazy-lock.json 5 | -------------------------------------------------------------------------------- /lua/setup/autopairs.lua: -------------------------------------------------------------------------------- 1 | 2 | require("nvim-autopairs").setup({}) 3 | -------------------------------------------------------------------------------- /lua/setup/mini-bracketed.lua: -------------------------------------------------------------------------------- 1 | require("mini.bracketed").setup() 2 | -------------------------------------------------------------------------------- /lua/setup/mini-bufremove.lua: -------------------------------------------------------------------------------- 1 | require("mini.bufremove").setup() 2 | -------------------------------------------------------------------------------- /lua/setup/mini-surround.lua: -------------------------------------------------------------------------------- 1 | require("mini.surround").setup() 2 | -------------------------------------------------------------------------------- /lua/setup/themes/zenbones.lua: -------------------------------------------------------------------------------- 1 | vim.cmd('colorscheme zenbones') 2 | -------------------------------------------------------------------------------- /lua/setup/notify.lua: -------------------------------------------------------------------------------- 1 | require("notify").setup({ 2 | top_down = false, 3 | }) 4 | -------------------------------------------------------------------------------- /lua/setup/auto-session.lua: -------------------------------------------------------------------------------- 1 | require("auto-session").setup({ 2 | log_level = "error", 3 | }) 4 | -------------------------------------------------------------------------------- /lua/setup/kb.lua: -------------------------------------------------------------------------------- 1 | local conf = { 2 | name = "Kinesis A360", 3 | layout = {}, 4 | } 5 | 6 | require("qmk").setup(conf) 7 | -------------------------------------------------------------------------------- /lua/setup/highlight-colors.lua: -------------------------------------------------------------------------------- 1 | require("nvim-highlight-colors").setup({ 2 | render = "virtual", -- or 'foreground' or 'first_column' 3 | virtual_symbol = "󰧞", 4 | }) 5 | -------------------------------------------------------------------------------- /lua/setup/pounce.lua: -------------------------------------------------------------------------------- 1 | require("pounce").setup({ 2 | accept_keys = "NTESIROAGJKDFVBYMCXWPQZ", 3 | accept_best_key = "", 4 | multi_window = true, 5 | debug = false, 6 | }) 7 | -------------------------------------------------------------------------------- /lua/setup/mini-indentscope.lua: -------------------------------------------------------------------------------- 1 | require("mini.indentscope").setup({ 2 | symbol = "▎", 3 | draw = { 4 | animation = require("mini.indentscope").gen_animation.none(), 5 | }, 6 | }) 7 | -------------------------------------------------------------------------------- /lua/setup/gitsigns.lua: -------------------------------------------------------------------------------- 1 | -- gitsigns setup 2 | require("gitsigns").setup({ 3 | -- numhl = true, 4 | -- signcolumn = false, 5 | current_line_blame_opts = { 6 | delay = 0, 7 | }, 8 | }) 9 | -------------------------------------------------------------------------------- /filetype.lua: -------------------------------------------------------------------------------- 1 | -- note only needed when working with zmk. goes in the config root. 2 | vim.filetype.add({ 3 | extension = { 4 | keymap = "dts", 5 | njk = "html", 6 | hbs = "html", 7 | }, 8 | }) 9 | -------------------------------------------------------------------------------- /lua/setup/comment.lua: -------------------------------------------------------------------------------- 1 | require("Comment").setup({ 2 | toggler = { 3 | line = "", 4 | block = "", 5 | }, 6 | opleader = { 7 | line = "", 8 | block = "", 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /lua/setup/spelling.lua: -------------------------------------------------------------------------------- 1 | -- Use spelling for markdown files ‘]s’ to find next, ‘[s’ for previous, 'z=‘ for suggestions when on one. 2 | vim.api.nvim_create_autocmd("FileType", { 3 | pattern = { "html", "markdown", "text" }, 4 | callback = function() 5 | vim.opt_local.spell = true 6 | end, 7 | }) 8 | -------------------------------------------------------------------------------- /lua/setup/oil.lua: -------------------------------------------------------------------------------- 1 | require("oil").setup({ 2 | columns = { 3 | "icon", 4 | }, 5 | skip_confirm_for_simple_edits = true, 6 | view_options = { 7 | -- Show files and directories that start with "." 8 | show_hidden = true, 9 | }, 10 | keymaps = { 11 | [""] = { "actions.select", opts = { vertical = true } }, 12 | }, 13 | }) 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Neovim config 2 | 3 | This is my day to day configuration for Neovim. I work as a front-end developer, using languages like CSS, JavaScript (and their superset equivalents like Sass and TypeScript) and HTML. 4 | 5 | This is the config I use on YouTube: https://youtube.com/@benfrainuk 6 | 7 | These files live in the `.config/nvim` folder of my user directory. 8 | -------------------------------------------------------------------------------- /lua/setup/zen-mode.lua: -------------------------------------------------------------------------------- 1 | require("zen-mode").setup({ 2 | window = { 3 | width = 90, 4 | options = { 5 | number = false, 6 | relativenumber = false, 7 | signcolumn = "no", 8 | cursorcolumn = false, 9 | }, 10 | }, 11 | plugins = { 12 | kitty = { 13 | enabled = true, 14 | font = "+2", 15 | }, 16 | }, 17 | }) 18 | -------------------------------------------------------------------------------- /lua/setup/mini-move.lua: -------------------------------------------------------------------------------- 1 | require("mini.move").setup({ 2 | mappings = { 3 | -- Move visual selection in Visual mode. 4 | left = "", 5 | right = "", 6 | down = "", 7 | up = "", 8 | 9 | -- Move current line in Normal mode 10 | line_left = "", 11 | line_right = "", 12 | line_down = "", 13 | line_up = "", 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /lua/setup/qmk.lua: -------------------------------------------------------------------------------- 1 | require("qmk").setup({ 2 | name = "LAYOUT_pretty", 3 | variant = "zmk", 4 | layout = { 5 | "x x x x x x x _ _ _ _ _ _ _ _ _ _ x x x x x x x", 6 | "x x x x x x x _ _ _ _ _ _ _ _ _ _ x x x x x x x", 7 | "x x x x x x x _ x x x _ _ x x x _ x x x x x x x", 8 | "x x x x x x _ x x x x _ _ x x x x _ x x x x x x", 9 | "x x x x x _ _ _ x x x _ _ x x x _ _ _ x x x x x", 10 | }, 11 | }) 12 | -------------------------------------------------------------------------------- /lua/setup/which-key.lua: -------------------------------------------------------------------------------- 1 | require("which-key").setup({ 2 | preset = "helix", 3 | delay = 0, 4 | win = { 5 | height = { 6 | max = math.huge, 7 | }, 8 | }, 9 | plugins = { 10 | spelling = { 11 | enabled = false, 12 | }, 13 | }, 14 | icons = { 15 | rules = false, 16 | breadcrumb = " ", -- symbol used in the command line area that shows your active key combo 17 | separator = "󱦰 ", -- symbol used between a key and it's label 18 | group = "󰹍 ", -- symbol prepended to a group 19 | }, 20 | }) 21 | -------------------------------------------------------------------------------- /lua/setup/navbuddy.lua: -------------------------------------------------------------------------------- 1 | local navbuddy = require("nvim-navbuddy") 2 | local actions = require("nvim-navbuddy.actions") 3 | 4 | navbuddy.setup({ 5 | window = { 6 | border = "double", 7 | }, 8 | mappings = { 9 | [""] = actions.next_sibling(), -- down 10 | [""] = actions.previous_sibling(), -- up 11 | [""] = actions.parent(), -- Move to left panel 12 | [""] = actions.children(), -- Move to right panel 13 | [""] = actions.root(), -- Move to first panel 14 | }, 15 | lsp = { 16 | auto_attach = true, 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /lua/setup/themes/nightfox.lua: -------------------------------------------------------------------------------- 1 | -- Nightfox config 2 | local nightfox = require("nightfox") 3 | nightfox.setup({ 4 | options = { 5 | dim_inactive = true, 6 | styles = { 7 | comments = "italic", 8 | keywords = "bold", 9 | functions = "italic,bold", 10 | }, 11 | inverse = { 12 | search = true, 13 | match_paren = true, 14 | }, 15 | }, 16 | groups = { 17 | all = { 18 | CursorLine = { bg = "#353A54" }, 19 | CursorColumn = { bg = "#353A54" }, 20 | }, 21 | }, 22 | }) 23 | 24 | vim.cmd("colorscheme duskfox") -- Put your favorite colorscheme here 25 | -------------------------------------------------------------------------------- /lua/setup/treesitter.lua: -------------------------------------------------------------------------------- 1 | require("nvim-treesitter.configs").setup({ 2 | autotag = { 3 | enable = true, 4 | filetypes = { 5 | "html", 6 | "javascript", 7 | "typescript", 8 | "markdown", 9 | }, 10 | }, 11 | ensure_installed = { 12 | "c", 13 | "css", 14 | "scss", 15 | "typescript", 16 | "lua", 17 | "html", 18 | "javascript", 19 | "json", 20 | "php", 21 | "rust", 22 | "yaml", 23 | "vim", 24 | "toml", 25 | }, 26 | highlight = { enable = true }, 27 | incremental_selection = { 28 | enable = true, 29 | keymaps = { 30 | init_selection = "", 31 | scope_incremental = "", 32 | node_incremental = "", 33 | node_decremental = "", 34 | }, 35 | }, 36 | }) 37 | -------------------------------------------------------------------------------- /lua/setup/blink.lua: -------------------------------------------------------------------------------- 1 | return { 2 | keymap = { 3 | preset = "enter", 4 | }, 5 | appearance = { 6 | use_nvim_cmp_as_default = true, 7 | nerd_font_variant = "mono", 8 | }, 9 | sources = { 10 | default = { "lsp", "path", "snippets", "buffer" }, 11 | min_keyword_length = function() 12 | return vim.bo.filetype == "markdown" and 4 or 0 13 | end, 14 | providers = { 15 | lsp = { 16 | fallbacks = {}, 17 | }, 18 | }, 19 | }, 20 | completion = { 21 | documentation = { window = { border = "single" } }, 22 | menu = { 23 | border = "single", 24 | }, 25 | -- ghost_text = { enabled = true }, 26 | list = { 27 | selection = { 28 | preselect = function(ctx) 29 | return ctx.mode ~= "cmdline" 30 | end, 31 | auto_insert = function(ctx) 32 | return ctx.mode ~= "cmdline" 33 | end, 34 | }, 35 | }, 36 | }, 37 | signature = { window = { border = "single" } }, 38 | } 39 | -------------------------------------------------------------------------------- /init.lua: -------------------------------------------------------------------------------- 1 | -- Map leader to comma. This lets me do a lot of shortcuts using both hands 2 | vim.g.mapleader = "," 3 | 4 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 5 | if not vim.loop.fs_stat(lazypath) then 6 | vim.fn.system({ 7 | "git", 8 | "clone", 9 | "--filter=blob:none", 10 | "--single-branch", 11 | "https://github.com/folke/lazy.nvim.git", 12 | lazypath, 13 | }) 14 | end 15 | vim.opt.runtimepath:prepend(lazypath) 16 | 17 | -- You will need to install language servers `npm i -g vscode-langservers-extracted` and `npm install -g typescript typescript-language-server` 18 | require("lazy").setup({ 19 | spec = "lazySetup", 20 | performance = { 21 | rtp = { 22 | disabled_plugins = { 23 | "gzip", 24 | "netrwPlugin", 25 | "tarPlugin", 26 | "tohtml", 27 | "tutor", 28 | "zipPlugin", 29 | }, 30 | }, 31 | }, 32 | ui = { 33 | border = "single", 34 | }, 35 | }) 36 | require("options") 37 | require("setup.spelling") 38 | require("mappings") 39 | -------------------------------------------------------------------------------- /lua/setup/themes/kanagawa.lua: -------------------------------------------------------------------------------- 1 | require("kanagawa").setup({ 2 | compile = true, 3 | dimInactive = true, 4 | overrides = function(colors) 5 | local theme = colors.theme 6 | local palette = colors.palette 7 | return { 8 | 9 | IndentBlanklineChar = { fg = palette.waveBlue2 }, 10 | MiniIndentscopeSymbol = { fg = palette.waveBlue2 }, 11 | PmenuSel = { blend = 0 }, 12 | NormalFloat = { bg = "none" }, 13 | FloatBorder = { bg = "none" }, 14 | FloatTitle = { bg = "none" }, 15 | CursorLineNr = { bg = theme.ui.bg_p2 }, 16 | Visual = { bg = palette.waveBlue2 }, 17 | 18 | -- Save an hlgroup with dark background and dimmed foreground 19 | -- so that you can use it where your still want darker windows. 20 | -- E.g.: autocmd TermOpen * setlocal winhighlight=Normal:NormalDark 21 | NormalDark = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m3 }, 22 | 23 | -- Popular plugins that open floats will link to NormalFloat by default; 24 | -- set their background accordingly if you wish to keep them dark and borderless 25 | LazyNormal = { bg = theme.ui.bg_m3, fg = theme.ui.fg_dim }, 26 | } 27 | end, 28 | colors = { 29 | theme = { 30 | all = { 31 | ui = { 32 | bg_gutter = "none", 33 | }, 34 | }, 35 | }, 36 | }, 37 | }) 38 | 39 | require("kanagawa").load("wave") 40 | -------------------------------------------------------------------------------- /lua/setup/conform.lua: -------------------------------------------------------------------------------- 1 | require("conform").setup({ 2 | formatters_by_ft = { 3 | lua = { "stylua" }, 4 | javascript = { "prettierd", "prettier", stop_after_first = true }, 5 | javascriptreact = { "prettierd", "prettier", stop_after_first = true }, 6 | typescriptreact = { "prettierd", "prettier", stop_after_first = true }, 7 | typescript = { "prettierd", "prettier", stop_after_first = true }, 8 | css = { "prettierd", "prettier" }, 9 | scss = { "prettierd", "prettier" }, 10 | markdown = { "prettierd", "prettier" }, 11 | html = { "prettierd", "prettier" }, 12 | json = { "prettierd", "prettier" }, 13 | yaml = { "prettierd", "prettier" }, 14 | graphql = { "prettierd", "prettier" }, 15 | md = { "prettierd", "prettier" }, 16 | txt = { "prettierd", "prettier" }, 17 | }, 18 | formatters = { 19 | stylua = { 20 | args = { "--indent-width", "2", "--indent-type", "Spaces", "-" }, 21 | }, 22 | prettier = { 23 | require_cwd = true, 24 | cwd = require("conform.util").root_file({ 25 | "package.json", 26 | ".prettierrc", 27 | ".prettierrc.json", 28 | ".prettierrc.yml", 29 | ".prettierrc.yaml", 30 | ".prettierrc.json5", 31 | ".prettierrc.js", 32 | ".prettierrc.cjs", 33 | ".prettierrc.mjs", 34 | ".prettierrc.toml", 35 | "prettier.config.js", 36 | "prettier.config.cjs", 37 | "prettier.config.mjs", 38 | }), 39 | }, 40 | }, 41 | -- Set up format-on-save 42 | -- don't want it formatting with lsp if Prettier isn't available 43 | format_on_save = { timeout_ms = 1500, lsp_format = "never" }, 44 | }) 45 | -------------------------------------------------------------------------------- /lua/setup/fzf.lua: -------------------------------------------------------------------------------- 1 | -- Hey Ben, you always forget this! When you want to search for something literal, say 'url(' you can use this: 2 | -- `url( -- -F` in the search box. Everything after the double dash is the option you are passing to FZF and in this case that would be Fixed String (and not trying to parse as a regex) 3 | local path = require("fzf-lua.path") 4 | get_line_and_path = function(selected, opts) 5 | local file_and_path = path.entry_to_file(selected[1], opts).stripped 6 | vim.print(file_and_path) 7 | if vim.o.clipboard == "unnamed" then 8 | vim.fn.setreg([[*]], file_and_path) 9 | elseif vim.o.clipboard == "unnamedplus" then 10 | vim.fn.setreg([[+]], file_and_path) 11 | else 12 | vim.fn.setreg([["]], file_and_path) 13 | end 14 | -- copy to the yank register regardless 15 | vim.fn.setreg([[0]], file_and_path) 16 | end 17 | 18 | require("fzf-lua").setup({ 19 | "border-fused", 20 | fzf_opts = { ["--wrap"] = true }, 21 | previewers = { 22 | builtin = { 23 | syntax_limit_b = -102400, -- 100KB limit on highlighting files 24 | }, 25 | }, 26 | winopts = { 27 | preview = { 28 | wrap = true, 29 | }, 30 | }, 31 | grep = { 32 | rg_glob = true, 33 | -- first returned string is the new search query 34 | -- second returned string are (optional) additional rg flags 35 | -- @return string, string? 36 | rg_glob_fn = function(query, opts) 37 | local regex, flags = query:match("^(.-)%s%-%-(.*)$") 38 | -- If no separator is detected will return the original query 39 | return (regex or query), flags 40 | end, 41 | }, 42 | defaults = { 43 | git_icons = false, 44 | file_icons = false, 45 | color_icons = false, 46 | formatter = "path.filename_first", 47 | }, 48 | actions = { 49 | files = { 50 | true, 51 | ["ctrl-y"] = { fn = get_line_and_path, exec_silent = true }, 52 | }, 53 | }, 54 | }) 55 | -------------------------------------------------------------------------------- /lua/setup/snacks.lua: -------------------------------------------------------------------------------- 1 | return { 2 | bigfile = { enabled = true }, 3 | dashboard = { enabled = false }, 4 | indent = { 5 | enabled = true, 6 | char = "▎", 7 | animate = { enabled = false }, 8 | indent = { 9 | only_current = true, 10 | only_scope = true, 11 | }, 12 | scope = { 13 | enabled = true, 14 | only_current = true, 15 | only_scope = true, 16 | underline = false, 17 | }, 18 | chunk = { 19 | enabled = true, 20 | only_current = true, 21 | }, 22 | -- filter for buffers, turn off the indents for markdown 23 | filter = function(buf) 24 | return vim.g.snacks_indent ~= false 25 | and vim.b[buf].snacks_indent ~= false 26 | and vim.bo[buf].buftype == "" 27 | and vim.bo[buf].filetype ~= "markdown" 28 | end, 29 | }, 30 | input = { enabled = true }, 31 | notifier = { 32 | enabled = true, 33 | win = { 34 | backdrop = { 35 | transparent = false, 36 | }, 37 | }, 38 | }, 39 | quickfile = { enabled = false }, 40 | scroll = { enabled = false }, 41 | statuscolumn = { enabled = true }, 42 | words = { enabled = false }, 43 | toggle = { 44 | which_key = true, -- integrate with which-key to show enabled/disabled icons and colors 45 | notify = true, -- show a notification when toggling 46 | -- icons for enabled/disabled states 47 | icon = { 48 | enabled = " ", 49 | disabled = " ", 50 | }, 51 | -- colors for enabled/disabled states 52 | color = { 53 | enabled = "green", 54 | disabled = "yellow", 55 | }, 56 | }, 57 | zen = { 58 | minimal = true, 59 | toggles = { 60 | dim = false, 61 | }, 62 | win = {}, 63 | show = { 64 | statusline = false, 65 | tabline = false, 66 | }, 67 | }, 68 | styles = { 69 | zen = { 70 | backdrop = { 71 | transparent = false, 72 | }, 73 | width = 100, 74 | wo = { 75 | number = false, 76 | signcolumn = "no", 77 | cursorcolumn = false, 78 | relativenumber = false, 79 | }, 80 | }, 81 | notification = { 82 | wo = { 83 | spell = false, 84 | winblend = 0, 85 | }, 86 | }, 87 | }, 88 | } 89 | -------------------------------------------------------------------------------- /lua/setup/telescope.lua: -------------------------------------------------------------------------------- 1 | -- Telescope Global remapping 2 | local action_state = require("telescope.actions.state") 3 | local actions = require("telescope.actions") 4 | local fb_actions = require("telescope._extensions.file_browser.actions") 5 | 6 | --- Insert filename into the current buffer and keeping the insert mode. 7 | actions.insert_name_i = function(prompt_bufnr) 8 | local symbol = action_state.get_selected_entry().ordinal 9 | actions.close(prompt_bufnr) 10 | vim.schedule(function() 11 | vim.cmd([[startinsert]]) 12 | vim.api.nvim_put({ symbol }, "", true, true) 13 | end) 14 | end 15 | 16 | --- Insert file path and name into the current buffer and keeping the insert mode. 17 | actions.insert_name_and_path_i = function(prompt_bufnr) 18 | local symbol = action_state.get_selected_entry().value 19 | actions.close(prompt_bufnr) 20 | vim.schedule(function() 21 | vim.cmd([[startinsert]]) 22 | vim.api.nvim_put({ symbol }, "", true, true) 23 | end) 24 | end 25 | 26 | require("telescope").setup({ 27 | defaults = { 28 | sorting_strategy = "descending", 29 | prompt_prefix = "  ", 30 | winblend = 25, 31 | mappings = { 32 | i = { 33 | [""] = actions.close, 34 | [""] = actions.smart_send_to_qflist + actions.open_qflist, 35 | }, 36 | }, 37 | }, 38 | extensions = { 39 | file_browser = { 40 | theme = "ivy", 41 | hidden = true, 42 | path = "%:p:h", 43 | mappings = { 44 | ["i"] = { 45 | [""] = fb_actions.move, 46 | [""] = fb_actions.goto_parent_dir, 47 | [""] = actions.insert_name_i, 48 | [""] = actions.insert_name_and_path_i, 49 | }, 50 | }, 51 | }, 52 | }, 53 | pickers = { 54 | find_files = { 55 | theme = "ivy", 56 | find_command = { "rg", "--files", "--hidden", "-g", "!.git" }, 57 | }, 58 | live_grep = { 59 | theme = "ivy", 60 | }, 61 | buffers = { 62 | theme = "ivy", 63 | sort_mru = true, 64 | ignore_current_buffer = true, 65 | mappings = { 66 | i = { 67 | [""] = "delete_buffer", 68 | }, 69 | n = { 70 | [""] = "delete_buffer", 71 | }, 72 | }, 73 | }, 74 | }, 75 | }) 76 | 77 | require("telescope").load_extension("fzf") 78 | require("telescope").load_extension("file_browser") 79 | -------------------------------------------------------------------------------- /lua/setup/lsp.lua: -------------------------------------------------------------------------------- 1 | local capabilities = require("blink.cmp").get_lsp_capabilities() 2 | 3 | -- Give me rounded borders everywhere 4 | local orig_util_open_floating_preview = vim.lsp.util.open_floating_preview 5 | function vim.lsp.util.open_floating_preview(contents, syntax, opts, ...) 6 | opts = opts or {} 7 | opts.border = "rounded" 8 | return orig_util_open_floating_preview(contents, syntax, opts, ...) 9 | end 10 | 11 | -- LSP Server config 12 | require("lspconfig").cssls.setup({ 13 | capabilities = capabilities, 14 | settings = { 15 | css = { 16 | lint = { 17 | emptyRules = "ignore", 18 | duplicateProperties = "warning", 19 | }, 20 | }, 21 | scss = { 22 | lint = { 23 | idSelector = "warning", 24 | zeroUnits = "warning", 25 | duplicateProperties = "warning", 26 | emptyRules = nil, 27 | }, 28 | completion = { 29 | completePropertyWithSemicolon = true, 30 | triggerPropertyValueCompletion = true, 31 | }, 32 | }, 33 | }, 34 | on_attach = function(client) 35 | client.server_capabilities.document_formatting = false 36 | end, 37 | }) 38 | require("lspconfig").ts_ls.setup({ 39 | capabilities = capabilities, 40 | on_attach = function(client) 41 | client.server_capabilities.document_formatting = false 42 | end, 43 | }) 44 | 45 | require("lspconfig").html.setup({ 46 | capabilities = capabilities, 47 | on_attach = function(client) 48 | client.server_capabilities.document_formatting = false 49 | end, 50 | }) 51 | 52 | require("lspconfig").stylelint_lsp.setup({ 53 | filetypes = { "css", "scss" }, 54 | root_dir = require("lspconfig").util.root_pattern("package.json", ".git"), 55 | settings = { 56 | stylelintplus = { 57 | -- see available options in stylelint-lsp documentation 58 | }, 59 | }, 60 | on_attach = function(client) 61 | client.server_capabilities.document_formatting = false 62 | end, 63 | }) 64 | 65 | -- require("lspconfig").eslint.setup({ 66 | -- root_dir = require("lspconfig").util.root_pattern("package.json", ".git"), 67 | -- on_attach = function(client) 68 | -- client.server_capabilities.document_formatting = false 69 | -- end, 70 | -- }) 71 | 72 | -- LSP Prevents inline buffer annotations 73 | vim.diagnostic.open_float() 74 | vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { 75 | virtual_text = false, 76 | signs = true, 77 | underline = true, 78 | update_on_insert = false, 79 | }) 80 | -------------------------------------------------------------------------------- /lua/setup/themes/catppuccin.lua: -------------------------------------------------------------------------------- 1 | vim.g.catppuccin_flavour = "macchiato" -- latte, frappe, macchiato, mocha 2 | require("catppuccin").setup({ 3 | dim_inactive = { 4 | enabled = true, 5 | shade = "dark", 6 | percentage = 0.15, 7 | }, 8 | transparent_background = false, 9 | term_colors = false, 10 | compile = { 11 | enabled = true, 12 | path = vim.fn.stdpath("cache") .. "/catppuccin", 13 | }, 14 | styles = { 15 | comments = { "italic" }, 16 | conditionals = { "italic" }, 17 | loops = {}, 18 | functions = {}, 19 | keywords = {}, 20 | strings = {}, 21 | variables = {}, 22 | numbers = {}, 23 | booleans = {}, 24 | properties = {}, 25 | types = {}, 26 | operators = {}, 27 | }, 28 | integrations = { 29 | treesitter = true, 30 | native_lsp = { 31 | enabled = true, 32 | virtual_text = { 33 | errors = { "italic" }, 34 | hints = { "italic" }, 35 | warnings = { "italic" }, 36 | information = { "italic" }, 37 | }, 38 | underlines = { 39 | errors = { "underline" }, 40 | hints = { "underline" }, 41 | warnings = { "underline" }, 42 | information = { "underline" }, 43 | }, 44 | }, 45 | coc_nvim = false, 46 | lsp_trouble = false, 47 | cmp = true, 48 | lsp_saga = false, 49 | gitgutter = false, 50 | gitsigns = true, 51 | leap = false, 52 | telescope = true, 53 | nvimtree = { 54 | enabled = false, 55 | show_root = true, 56 | transparent_panel = false, 57 | }, 58 | neotree = { 59 | enabled = false, 60 | show_root = true, 61 | transparent_panel = false, 62 | }, 63 | dap = { 64 | enabled = false, 65 | enable_ui = false, 66 | }, 67 | which_key = false, 68 | indent_blankline = { 69 | enabled = true, 70 | colored_indent_levels = false, 71 | }, 72 | dashboard = false, 73 | neogit = false, 74 | vim_sneak = false, 75 | fern = false, 76 | barbar = false, 77 | bufferline = false, 78 | markdown = true, 79 | lightspeed = false, 80 | ts_rainbow = false, 81 | hop = false, 82 | notify = true, 83 | telekasten = false, 84 | symbols_outline = true, 85 | mini = false, 86 | aerial = false, 87 | vimwiki = false, 88 | beacon = false, 89 | }, 90 | color_overrides = {}, 91 | highlight_overrides = {}, 92 | custom_highlights = { 93 | CursorLine = { bg = "#353A54" }, 94 | CursorColumn = { bg = "#353A54" }, 95 | }, 96 | }) 97 | 98 | vim.cmd([[colorscheme catppuccin]]) 99 | -------------------------------------------------------------------------------- /lua/lazySetup.lua: -------------------------------------------------------------------------------- 1 | -- returns the require for use in `config` parameter of lazy's use 2 | -- expects the name of the config file 3 | function get_setup(name) 4 | return function() 5 | require("setup." .. name) 6 | end 7 | end 8 | 9 | return { 10 | { "rebelot/kanagawa.nvim", config = get_setup("themes/kanagawa"), priority = 1000, lazy = false }, 11 | -- { "stevearc/dressing.nvim", event = "VeryLazy" }, 12 | { "stevearc/oil.nvim", event = "VeryLazy", config = get_setup("oil") }, 13 | { 14 | "stevearc/conform.nvim", 15 | event = { "BufWritePre" }, 16 | cmd = { "ConformInfo" }, 17 | config = get_setup("conform"), 18 | }, 19 | { "mbbill/undotree" }, 20 | { "LudoPinelli/comment-box.nvim", event = "VeryLazy" }, 21 | { "numToStr/Comment.nvim", lazy = false, config = get_setup("Comment") }, 22 | { "rlane/pounce.nvim", config = get_setup("pounce") }, 23 | { 24 | "nvim-lualine/lualine.nvim", 25 | config = get_setup("lualine"), 26 | event = "VeryLazy", 27 | }, 28 | { 29 | "folke/which-key.nvim", 30 | config = get_setup("which-key"), 31 | event = "VeryLazy", 32 | }, 33 | { "brenoprata10/nvim-highlight-colors", config = get_setup("highlight-colors") }, 34 | { 35 | "nvim-treesitter/nvim-treesitter", 36 | config = get_setup("treesitter"), 37 | build = ":TSUpdate", 38 | event = "BufReadPost", 39 | }, 40 | { 41 | "folke/snacks.nvim", 42 | priority = 1000, 43 | lazy = false, 44 | opts = require("setup.snacks"), 45 | }, 46 | { 47 | "saghen/blink.cmp", 48 | lazy = false, -- lazy loading handled internally 49 | -- optional: provides snippets for the snippet source 50 | dependencies = "rafamadriz/friendly-snippets", 51 | version = "*", 52 | opts = require("setup.blink"), 53 | }, 54 | { 55 | "lewis6991/gitsigns.nvim", 56 | event = "BufReadPre", 57 | config = get_setup("gitsigns"), 58 | }, 59 | { 60 | "neovim/nvim-lspconfig", 61 | config = get_setup("lsp"), 62 | dependencies = { "saghen/blink.cmp" }, 63 | }, 64 | { 65 | "ibhagwan/fzf-lua", 66 | -- optional for icon support 67 | dependencies = { "nvim-tree/nvim-web-devicons" }, 68 | config = get_setup("fzf"), 69 | }, 70 | { "rmagatti/auto-session", config = get_setup("auto-session") }, 71 | { "echasnovski/mini.ai", config = get_setup("mini-ai"), version = false }, 72 | { "echasnovski/mini.bracketed", config = get_setup("mini-bracketed"), version = false }, 73 | { "echasnovski/mini.move", config = get_setup("mini-move"), version = false }, 74 | { "windwp/nvim-ts-autotag", event = "InsertEnter" }, 75 | { 76 | "windwp/nvim-autopairs", 77 | config = get_setup("autopairs"), 78 | }, 79 | { 80 | "kylechui/nvim-surround", 81 | event = "VeryLazy", 82 | config = function() 83 | require("nvim-surround").setup() 84 | end, 85 | }, 86 | { "EdenEast/nightfox.nvim", config = get_setup("nightfox"), enabled = false }, 87 | { "folke/tokyonight.nvim", config = get_setup("tokyonight"), enabled = false }, 88 | { "catppuccin/nvim", name = "catppuccin", config = get_setup("catppuccin"), enabled = false }, 89 | } 90 | -------------------------------------------------------------------------------- /lua/options.lua: -------------------------------------------------------------------------------- 1 | local indent = 4 2 | local opt = vim.opt -- to set options 3 | opt.backspace = { "indent", "eol", "start" } 4 | opt.clipboard = "unnamedplus" 5 | opt.completeopt = "menu,menuone,noselect" 6 | opt.cursorline = true 7 | opt.cursorcolumn = true 8 | opt.encoding = "utf-8" -- Set default encoding to UTF-8 9 | opt.foldenable = true 10 | opt.foldmethod = "manual" 11 | -- opt.formatoptions = "l" 12 | opt.hidden = true -- Enable background buffers 13 | opt.hlsearch = true -- Highlight found searches 14 | opt.ignorecase = true -- Ignore case 15 | opt.inccommand = "split" -- Get a preview of replacements 16 | opt.incsearch = true -- Shows the match while typing 17 | opt.joinspaces = false -- No double spaces with join 18 | vim.o.lazyredraw = true 19 | opt.linebreak = true -- Stop words being broken on wrap 20 | opt.number = true -- Show line numbers 21 | opt.listchars = { tab = " ", trail = "·", nbsp = "%" } 22 | opt.list = true -- Show some invisible characters 23 | -- opt.relativenumber = true 24 | vim.o.shortmess = vim.o.shortmess .. "S" -- stops display of currentsearch match in cmdline area 25 | opt.equalalways = true -- make windows the same width when closing one 26 | opt.cursorlineopt = "both" -- should get cursorline in number too 27 | 28 | opt.expandtab = true 29 | opt.shiftwidth = indent 30 | opt.softtabstop = indent 31 | opt.tabstop = indent 32 | 33 | opt.showmode = false -- Don't display mode 34 | opt.scrolloff = 8 -- Lines of context 35 | opt.sidescrolloff = 8 -- Columns of context 36 | opt.signcolumn = "yes:1" -- always show signcolumns 37 | opt.smartcase = true -- Do not ignore case with capitals 38 | opt.spelllang = { "en_gb" } 39 | opt.splitbelow = true -- Put new windows below current 40 | opt.splitright = true -- Put new windows right of current 41 | -- opt.splitkeep = "screen" -- Stops screen jumping when splits below are opened 42 | opt.termguicolors = true -- You will have bad experience for diagnostic messages when it's default 4000. 43 | opt.title = true -- Allows neovom to send the Terminal details of the current window, instead of just getting 'v' 44 | -- Give me some fenced codeblock goodness 45 | vim.g.markdown_fenced_languages = { "html", "javascript", "typescript", "css", "scss", "lua", "vim" } 46 | vim.o.whichwrap = vim.o.whichwrap .. "<,>" -- Wrap movement between lines in edit mode with arrows 47 | opt.wrap = true 48 | -- opt.cc = "80" 49 | opt.mouse = "a" 50 | opt.guicursor = 51 | "n-v-c-sm:block-nCursor-blinkwait50-blinkon50-blinkoff50,i-ci-ve:ver25-Cursor-blinkon100-blinkoff100,r-cr-o:hor20" 52 | opt.undodir = vim.fn.stdpath("config") .. "/undo" 53 | opt.undofile = true 54 | -- vim.notify = require("notify") 55 | opt.jumpoptions = "view" 56 | opt.timeoutlen = 300 -- The time before a key sequence should complete 57 | opt.cpoptions:append(">") -- when you yank multiple times into a register, this puts each on a new line 58 | opt.nrformats:append("alpha") -- this means you can increment lists that have letters with `g ctrl-a` 59 | -- opt.pumblend = 5 -- partial opacity of pop up menu, this causes characters in lspkind to render incorrect width and means that you have to set up kitty to use narrow symbols. See https://github.com/kovidgoyal/kitty/discussions/7774#discussioncomment-10442608 60 | opt.ph = 15 -- the number is the number of entries to show before scrollbars, not px! 61 | opt.cmdheight = 0 62 | opt.virtualedit = "block" -- allows using visual blocks beyond the end of a line 63 | vim.g.editorconfig = false -- disable editor config as VSCode does not have it on by default 64 | 65 | local api = vim.api 66 | -- Highlight on yank 67 | local yankGrp = vim.api.nvim_create_augroup("YankHighlight", { clear = true }) 68 | api.nvim_create_autocmd("TextYankPost", { 69 | group = yankGrp, 70 | pattern = "*", 71 | callback = function() 72 | vim.highlight.on_yank() 73 | end, 74 | desc = "Highlight yank", 75 | }) 76 | 77 | -- show cursor line only in active window 78 | local cursorGrp = api.nvim_create_augroup("CursorLine", { clear = true }) 79 | api.nvim_create_autocmd({ "InsertLeave", "WinEnter" }, { pattern = "*", command = "set cursorline", group = cursorGrp }) 80 | api.nvim_create_autocmd( 81 | { "InsertEnter", "WinLeave" }, 82 | { pattern = "*", command = "set nocursorline", group = cursorGrp } 83 | ) 84 | 85 | -- show cursor col line only in active window 86 | local cursorColGrp = api.nvim_create_augroup("CursorColumn", { clear = true }) 87 | api.nvim_create_autocmd( 88 | { "InsertLeave", "WinEnter" }, 89 | { pattern = "*", command = "set cursorcolumn", group = cursorColGrp } 90 | ) 91 | api.nvim_create_autocmd( 92 | { "InsertEnter", "WinLeave" }, 93 | { pattern = "*", command = "set nocursorcolumn", group = cursorColGrp } 94 | ) 95 | 96 | -- show Blank Line only in active window 97 | -- local blanklineGrp = api.nvim_create_augroup("BlankLine", { clear = true }) 98 | -- api.nvim_create_autocmd( 99 | -- { "InsertLeave", "WinEnter" }, 100 | -- { pattern = "*", command = ":IndentBlanklineEnable", group = blanklineGrp } 101 | -- ) 102 | -- api.nvim_create_autocmd( 103 | -- { "InsertEnter", "WinLeave" }, 104 | -- { pattern = "*", command = ":IndentBlanklineDisable", group = blanklineGrp } 105 | -- ) 106 | 107 | -- auto-reload files when modified externally 108 | -- https://unix.stackexchange.com/a/383044 109 | vim.o.autoread = true 110 | vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "CursorHoldI", "FocusGained" }, { 111 | command = "if mode() != 'c' | checktime | endif", 112 | pattern = { "*" }, 113 | }) 114 | 115 | -- Don't want relative no on inactive Windows 116 | -- local relativeNo = api.nvim_create_augroup("RelativeNo", { clear = true }) 117 | -- 118 | -- api.nvim_create_autocmd({ "BufEnter", "FocusGained", "InsertLeave" }, { 119 | -- pattern = "*", 120 | -- group = relativeNo, 121 | -- callback = function() 122 | -- if not vim.g.zen_mode_active then 123 | -- vim.cmd([[set relativenumber]]) 124 | -- end 125 | -- end, 126 | -- }) 127 | -- 128 | -- api.nvim_create_autocmd({ "BufLeave", "FocusLost", "InsertEnter" }, { 129 | -- pattern = "*", 130 | -- group = relativeNo, 131 | -- callback = function() 132 | -- if not vim.g.zen_mode_active then 133 | -- vim.cmd([[set norelativenumber]]) 134 | -- end 135 | -- end, 136 | -- }) 137 | 138 | -- This is global settings for diagnostics 139 | vim.o.updatetime = 250 140 | vim.diagnostic.config({ 141 | virtual_text = false, 142 | signs = true, 143 | underline = true, 144 | update_in_insert = false, 145 | severity_sort = false, 146 | -- virtual_lines = { 147 | -- current_line = true, 148 | -- }, 149 | signs = { 150 | text = { 151 | [vim.diagnostic.severity.ERROR] = "󰅚 ", 152 | [vim.diagnostic.severity.WARN] = "󰳦 ", 153 | [vim.diagnostic.severity.HINT] = "󱡄 ", 154 | [vim.diagnostic.severity.INFO] = " ", 155 | }, 156 | }, 157 | }) 158 | -------------------------------------------------------------------------------- /lua/setup/lualine.lua: -------------------------------------------------------------------------------- 1 | local mode_map = { 2 | ["NORMAL"] = "N", 3 | ["O-PENDING"] = "N?", 4 | ["INSERT"] = "I", 5 | ["VISUAL"] = "V", 6 | ["V-BLOCK"] = "VB", 7 | ["V-LINE"] = "VL", 8 | ["V-REPLACE"] = "VR", 9 | ["REPLACE"] = "R", 10 | ["COMMAND"] = "!", 11 | ["SHELL"] = "SH", 12 | ["TERMINAL"] = "T", 13 | ["EX"] = "X", 14 | ["S-BLOCK"] = "SB", 15 | ["S-LINE"] = "SL", 16 | ["SELECT"] = "S", 17 | ["CONFIRM"] = "Y?", 18 | ["MORE"] = "M", 19 | } 20 | 21 | -- stolen/amended from https://github.com/leonasdev/.dotfiles/blob/master/.config/nvim/lua/util/statusline.lua 22 | local function getScrollPos() 23 | local progressIcons = { 24 | "󰋙 ", 25 | "󰫃 ", 26 | "󰫄 ", 27 | "󰫅 ", 28 | "󰫆 ", 29 | "󰫇 ", 30 | "󰫈 ", 31 | } 32 | local current = vim.api.nvim_win_get_cursor(0)[1] 33 | local lines = vim.api.nvim_buf_line_count(0) 34 | local i = math.floor((current - 1) / lines * #progressIcons) + 1 35 | local sbar = string.format(progressIcons[i]) 36 | 37 | local colPre = "c" 38 | local col = "%c " 39 | 40 | return string.format("%s%s%s", colPre, col, sbar) 41 | end 42 | 43 | local function createDiffString() 44 | local diffparts = vim.b.gitsigns_status_dict 45 | local head = diffparts.head or "unknown" 46 | local head_and_icon = "󰘬 " .. head 47 | local added = diffparts.added or 0 48 | local removed = diffparts.removed or 0 49 | local changed = diffparts.changed or 0 50 | 51 | -- Start constructing the output string (thanks to fpohtmeh on Reddit for helping with this:https://www.reddit.com/r/neovim/comments/1h866d1/comment/m0sujbd/?context=3) 52 | local output = string.format("%%#lualine_b_normal#%s", head_and_icon) 53 | local hasChanges = false 54 | 55 | if added > 0 or removed > 0 or changed > 0 then 56 | output = output .. string.format("%%#lualine_b_normal#%s", "(") 57 | hasChanges = true 58 | end 59 | 60 | if added > 0 then 61 | output = output .. string.format("%%#lualine_b_diff_added_normal#+%d", added) 62 | end 63 | 64 | if removed > 0 then 65 | output = output .. string.format("%%#lualine_b_diff_removed_normal#-%d", removed) 66 | end 67 | 68 | if changed > 0 then 69 | output = output .. string.format("%%#lualine_b_diff_modified_normal#~%d", changed) 70 | end 71 | 72 | -- Close the parentheses if any changes were added 73 | if hasChanges then 74 | output = output .. string.format("%%#lualine_b_normal#%s", ")") 75 | end 76 | 77 | -- Return the final output 78 | return output 79 | end 80 | 81 | -- Make a global table 82 | wordCount = {} 83 | -- Now add a function to it for the job needed 84 | function wordCount.getWords() 85 | if vim.bo.filetype == "md" or vim.bo.filetype == "txt" or vim.bo.filetype == "markdown" then 86 | if vim.fn.wordcount().visual_words == 1 then 87 | return tostring(vim.fn.wordcount().visual_words) .. " word" 88 | elseif not (vim.fn.wordcount().visual_words == nil) then 89 | return tostring(vim.fn.wordcount().visual_words) .. " words" 90 | else 91 | return tostring(vim.fn.wordcount().words) .. " words" 92 | end 93 | else 94 | return "Not a text file" 95 | end 96 | end 97 | 98 | --- @param trunc_width number trunctates component when screen width is less then trunc_width 99 | --- @param trunc_len number truncates component to trunc_len number of chars 100 | --- @param hide_width number hides component when window width is smaller then hide_width 101 | --- @param no_ellipsis boolean whether to disable adding '...' at end after truncation 102 | --- return function that can format the component accordingly 103 | local function trunc(trunc_width, trunc_len, hide_width, no_ellipsis) 104 | return function(str) 105 | local win_width = vim.fn.winwidth(0) 106 | if hide_width and win_width < hide_width then 107 | return "" 108 | elseif trunc_width and trunc_len and win_width < trunc_width and #str > trunc_len then 109 | return str:sub(1, trunc_len) .. (no_ellipsis and "" or "...") 110 | end 111 | return str 112 | end 113 | end 114 | 115 | local function diff_source() 116 | local gitsigns = vim.b.gitsigns_status_dict 117 | if gitsigns then 118 | return { 119 | added = gitsigns.added, 120 | modified = gitsigns.changed, 121 | removed = gitsigns.removed, 122 | } 123 | end 124 | end 125 | 126 | local function window() 127 | return vim.api.nvim_win_get_number(0) 128 | end 129 | 130 | -- adapted from https://www.reddit.com/r/neovim/comments/xy0tu1/cmdheight0_recording_macros_message/ 131 | local function show_macro_recording() 132 | local recording_register = vim.fn.reg_recording() 133 | if recording_register == "" then 134 | return "" 135 | else 136 | return "󰑋 " .. recording_register 137 | end 138 | end 139 | 140 | -- print(vim.inspect(nfColors)) 141 | require("lualine").setup({ 142 | options = { 143 | icons_enabled = true, 144 | theme = "auto", 145 | component_separators = { " ", " " }, 146 | section_separators = { left = "", right = "" }, 147 | disabled_filetypes = {}, 148 | }, 149 | sections = { 150 | lualine_a = { 151 | -- { "mode", fmt = trunc(80, 1, nil, true) }, 152 | { 153 | "mode", 154 | fmt = function(s) 155 | return mode_map[s] or s 156 | end, 157 | }, 158 | }, 159 | lualine_b = { 160 | { 161 | createDiffString, 162 | color = nil, 163 | }, 164 | }, 165 | lualine_c = { 166 | { "diagnostics", sources = { "nvim_diagnostic" }, draw_empty = false }, 167 | function() 168 | return "%=" 169 | end, 170 | { 171 | "filename", 172 | file_status = true, 173 | path = 0, 174 | shorting_target = 40, 175 | symbols = { 176 | modified = "󰐖 ", -- Text to show when the file is modified. 177 | readonly = " ", -- Text to show when the file is non-modifiable or readonly. 178 | unnamed = "[No Name]", -- Text to show for unnamed buffers. 179 | newfile = "[New]", -- Text to show for new created file before first writting 180 | }, 181 | }, 182 | { 183 | wordCount.getWords, 184 | color = { fg = "#333333", bg = "#eeeeee" }, 185 | separator = { left = "", right = "" }, 186 | cond = function() 187 | return wordCount.getWords() ~= "Not a text file" 188 | end, 189 | }, 190 | { 191 | "searchcount", 192 | }, 193 | { 194 | "selectioncount", 195 | }, 196 | { 197 | show_macro_recording, 198 | color = { fg = "#333333", bg = "#ff6666" }, 199 | separator = { left = "", right = "" }, 200 | }, 201 | }, 202 | lualine_y = { 203 | nil, 204 | }, 205 | lualine_x = { 206 | { getScrollPos, width = 100, padding = { left = 10, right = 1 } }, 207 | }, 208 | lualine_z = { nil }, 209 | }, 210 | inactive_sections = { 211 | lualine_a = { { window, color = { fg = "#26ffbb", bg = "#282828" } } }, 212 | lualine_b = { 213 | { 214 | "diff", 215 | source = diff_source, 216 | color_added = "#a7c080", 217 | color_modified = "#ffdf1b", 218 | color_removed = "#ff6666", 219 | }, 220 | }, 221 | lualine_c = { 222 | function() 223 | return "%=" 224 | end, 225 | { 226 | "filename", 227 | path = 1, 228 | shorting_target = 40, 229 | symbols = { 230 | modified = "󰐖 ", -- Text to show when the file is modified. 231 | readonly = " ", -- Text to show when the file is non-modifiable or readonly. 232 | unnamed = "[No Name]", -- Text to show for unnamed buffers. 233 | newfile = "[New]", -- Text to show for new created file before first writting 234 | }, 235 | }, 236 | }, 237 | lualine_x = { 238 | { place, padding = { left = 1, right = 1 } }, 239 | }, 240 | lualine_y = {}, 241 | lualine_z = {}, 242 | }, 243 | tabline = {}, 244 | extensions = { 245 | "quickfix", 246 | "oil", 247 | "fzf", 248 | }, 249 | }) 250 | 251 | local lualine = require("lualine") 252 | vim.api.nvim_create_autocmd("RecordingEnter", { 253 | callback = function() 254 | lualine.refresh() 255 | end, 256 | }) 257 | 258 | vim.api.nvim_create_autocmd("RecordingLeave", { 259 | callback = function() 260 | -- This is going to seem really weird! 261 | -- Instead of just calling refresh we need to wait a moment because of the nature of 262 | -- `vim.fn.reg_recording`. If we tell lualine to refresh right now it actually will 263 | -- still show a recording occuring because `vim.fn.reg_recording` hasn't emptied yet. 264 | -- So what we need to do is wait a tiny amount of time (in this instance 50 ms) to 265 | -- ensure `vim.fn.reg_recording` is purged before asking lualine to refresh. 266 | local timer = vim.loop.new_timer() 267 | timer:start( 268 | 50, 269 | 0, 270 | vim.schedule_wrap(function() 271 | lualine.refresh() 272 | end) 273 | ) 274 | end, 275 | }) 276 | -------------------------------------------------------------------------------- /lua/mappings.lua: -------------------------------------------------------------------------------- 1 | local km = vim.keymap 2 | 3 | -- Here is a utility function that closes any floating windows when you press escape 4 | local function close_floating() 5 | for _, win in pairs(vim.api.nvim_list_wins()) do 6 | if vim.api.nvim_win_get_config(win).relative == "win" then 7 | vim.api.nvim_win_close(win, false) 8 | end 9 | end 10 | end 11 | 12 | -- ┌ ┐ 13 | -- │ These define common comment styles like this │ 14 | -- └ ┘ 15 | km.set({ "n", "v" }, "x1", ":CBlbox12", { desc = "Comment - single side" }) 16 | km.set({ "n", "v" }, "x2", ":CBlbox18", { desc = "Comment - both sides" }) 17 | km.set("n", "x3", "CBline3", { desc = "Centered Line" }) 18 | km.set("n", "x4", "CBline5", { desc = "Centered Line Weighted" }) 19 | 20 | km.set("n", "u", ":Lazy update", { desc = "Lazy Update (Sync)" }) 21 | 22 | km.set("n", "n", "enew", { desc = "New File" }) 23 | 24 | km.set("n", "a", "ggVG", { desc = "Select All" }) 25 | 26 | -- Make visual yanks place the cursor back where started 27 | km.set("v", "y", "ygv", { desc = "Yank and reposition cursor" }) 28 | 29 | km.set("n", "", ":w", { desc = "Save file" }) 30 | 31 | km.set("n", "xu", ":UndotreeToggle", { desc = "Undo Tree" }) 32 | -- More molecular undo of text 33 | km.set("i", ".", ".u") 34 | km.set("i", "!", "!u") 35 | km.set("i", "?", "?u") 36 | km.set("i", ";", ";u") 37 | km.set("i", ":", ":u") 38 | 39 | km.set({ "n", "i" }, "", "") 40 | 41 | --nav buddy 42 | km.set({ "n" }, "xb", ":lua require('nvim-navbuddy').open()", { desc = "Nav Buddy" }) 43 | 44 | km.set("n", "", function() 45 | close_floating() 46 | vim.cmd(":noh") 47 | end, { silent = true, desc = "Remove Search Highlighting, Dismiss Popups" }) 48 | 49 | -- Easy add date/time 50 | function date() 51 | local pos = vim.api.nvim_win_get_cursor(0)[2] 52 | local line = vim.api.nvim_get_current_line() 53 | local nline = line:sub(0, pos) .. "# " .. os.date("%d.%m.%y") .. line:sub(pos + 1) 54 | vim.api.nvim_set_current_line(nline) 55 | vim.api.nvim_feedkeys("o", "n", true) 56 | end 57 | 58 | km.set("n", "xd", "lua date()", { desc = "Insert Date" }) 59 | 60 | km.set("n", "v", "gea", { desc = "Edit after last word" }) 61 | 62 | km.set("n", "j", [[(v:count > 5 ? "m'" . v:count : "") . 'j']], { expr = true, desc = "if j > 5 add to jumplist" }) 63 | 64 | km.set("n", "p", require("fzf-lua").files, { desc = "FZF Files" }) 65 | 66 | km.set("n", "", require("fzf-lua").resume, { desc = "FZF Resume" }) 67 | 68 | km.set("n", "r", require("fzf-lua").registers, { desc = "Registers" }) 69 | 70 | km.set("n", "m", require("fzf-lua").marks, { desc = "Marks" }) 71 | 72 | km.set("n", "k", require("fzf-lua").keymaps, { desc = "Keymaps" }) 73 | 74 | km.set("n", "f", require("fzf-lua").live_grep, { desc = "FZF Grep" }) 75 | 76 | km.set("n", "b", require("fzf-lua").buffers, { desc = "FZF Buffers" }) 77 | 78 | km.set("v", "8", require("fzf-lua").grep_visual, { desc = "FZF Selection" }) 79 | 80 | km.set("n", "7", require("fzf-lua").grep_cword, { desc = "FZF Word" }) 81 | 82 | km.set("n", "j", require("fzf-lua").helptags, { desc = "Help Tags" }) 83 | 84 | km.set("n", "gc", require("fzf-lua").git_bcommits, { desc = "Browse File Commits" }) 85 | 86 | km.set("n", "gs", require("fzf-lua").git_status, { desc = "Git Status" }) 87 | 88 | km.set("n", "s", require("fzf-lua").spell_suggest, { desc = "Spelling Suggestions" }) 89 | 90 | km.set("n", "cj", require("fzf-lua").lsp_definitions, { desc = "Jump to Definition" }) 91 | 92 | km.set( 93 | "n", 94 | "cs", 95 | ":lua require'fzf-lua'.lsp_document_symbols({winopts = {preview={wrap='wrap'}}})", 96 | { desc = "Document Symbols" } 97 | ) 98 | 99 | km.set("n", "cr", require("fzf-lua").lsp_references, { desc = "LSP References" }) 100 | 101 | km.set( 102 | "n", 103 | "cd", 104 | ":lua require'fzf-lua'.diagnostics_document({fzf_opts = { ['--wrap'] = true }})", 105 | { desc = "Document Diagnostics" } 106 | ) 107 | 108 | km.set( 109 | "n", 110 | "ca", 111 | ":lua require'fzf-lua'.lsp_code_actions({ winopts = {relative='cursor',row=1.01, col=0, height=0.2, width=0.4} })", 112 | { desc = "Code Actions" } 113 | ) 114 | 115 | km.set("n", "ch", function() 116 | vim.lsp.buf.hover() 117 | end, { desc = "Code Hover" }) 118 | 119 | km.set("n", "cl", function() 120 | vim.diagnostic.open_float(0, { scope = "line" }) 121 | end, { desc = "Line Diagnostics" }) 122 | 123 | km.set({ "v", "n" }, "cn", function() 124 | vim.lsp.buf.rename() 125 | end, { noremap = true, silent = true, desc = "Code Rename" }) 126 | 127 | km.set("n", "", "", { silent = true, desc = "Window Down" }) 128 | km.set("n", "", "", { silent = true, desc = "Window Up" }) 129 | km.set("n", "", "", { silent = true, desc = "Window Right" }) 130 | km.set("n", "", "", { silent = true, desc = "Window Left" }) 131 | km.set("n", "wr", "R", { silent = true, desc = "Window Resize" }) 132 | km.set("n", "=", "=", { silent = true, desc = "Window Equalise" }) 133 | 134 | -- Easier window switching with leader + Number 135 | -- Creates mappings like this: km.set("n", "2", "2w", { desc = "Move to Window 2" }) 136 | for i = 1, 4 do 137 | local lhs = "" .. i 138 | local rhs = i .. "w" 139 | km.set("n", lhs, rhs, { desc = "Move to Window " .. i }) 140 | end 141 | 142 | km.set({ "n", "v" }, "h", ":Pounce", { silent = true, desc = "Pounce" }) 143 | km.set("n", "H", ":PounceRepeat", { silent = true, desc = "Pounce Repeat" }) 144 | 145 | km.set("i", "", "", { desc = "Option+BS deletes whole word" }) 146 | 147 | -- Gitsigns specific for file specific git info/tools 148 | km.set("n", "gb", ":Gitsigns toggle_current_line_blame", { desc = "Git toggle line blame" }) 149 | km.set("n", "gp", ":Gitsigns preview_hunk", { desc = "Git preview hunk" }) 150 | km.set("n", "gr", ":Gitsigns reset_hunk", { desc = "Get reset hunk" }) 151 | 152 | km.set("n", "xs", ":SearchSession", { desc = "Search Sessions" }) 153 | 154 | km.set( 155 | "v", 156 | "xp", 157 | ":'<,'> w !pandoc --no-highlight --wrap=none | pbcopy ", 158 | { silent = true, desc = "Pandoc Export" } 159 | ) 160 | 161 | km.set("n", "xn", ":let @+=@%", { desc = "Copy Buffer name and path" }) 162 | 163 | km.set("n", "xc", ":g/console.lo/d", { desc = "Remove console.log" }) 164 | 165 | km.set("v", "o", "zA", { desc = "Toggle Fold" }) 166 | 167 | km.set({ "n", "x" }, "[p", 'exe "put! " . v:register', { desc = "Paste Above" }) 168 | km.set({ "n", "x" }, "]p", 'exe "put " . v:register', { desc = "Paste Below" }) 169 | 170 | -- This allows you to select, and paste over contents, without that pasted over contents going into the register, that means you can paste again without it inserting the thing you pasted over the last time 171 | km.set("x", "p", function() 172 | return 'pgv"' .. vim.v.register .. "y" 173 | end, { remap = false, expr = true }) 174 | 175 | km.set({ "n", "x" }, "", "", { desc = "Alternate File" }) 176 | km.set("n", "-", "Oil", { desc = "Open parent directory" }) 177 | -- This sets the ability to surround words with brackets and quotes with one key in visual mode 178 | -- local v_chars = { "(", ")", "[", "]", "{", "}", "'", '"' } 179 | -- for _, char in pairs(v_chars) do 180 | -- vim.keymap.set("v", char, "(nvim-surround-visual)" .. char) 181 | -- end 182 | -- 183 | -- Set file EOL 184 | km.set({ "n" }, "xl", ":set ff=dos", { desc = "EOL = CRLF" }) 185 | km.set({ "n" }, "xf", ":set ff=unix", { desc = "EOL = LF" }) 186 | 187 | -- Quick new split above/below 188 | km.set({ "n" }, "ws", "new", { desc = "New split below" }) 189 | km.set({ "n" }, "wv", "vnew", { desc = "New split right" }) 190 | 191 | km.set({ "n" }, "xw", function() 192 | return Snacks.notify.notify(wordCount.getWords(), { 193 | zindex = 1000, 194 | title = "Word Count", 195 | timeout = 3000, 196 | icon = "󰆙 ", 197 | }) 198 | end, { desc = "Word Count" }) 199 | 200 | -- get the file format of the current file 201 | km.set({ "n" }, "xt", function() 202 | local symbols = { 203 | unix = " LF", 204 | dos = " CRLF", 205 | mac = " CR", 206 | } 207 | 208 | local ft = vim.bo.fileformat 209 | local output = string.format("%s%s", ft, symbols[ft]) 210 | return Snacks.notify.notify(output, { 211 | icon = " ", 212 | title = "File Type", 213 | timeout = 2000, 214 | zindex = 1000, 215 | }) 216 | end, { desc = "Show File Format" }) 217 | 218 | -- Toggle Terminal, thanks https://www.reddit.com/r/neovim/comments/1bjhadj/efficiently_switching_between_neovim_and_terminal/ 219 | exitTerm = function() 220 | vim.cmd(":lua Snacks.terminal.toggle()") 221 | end 222 | km.set({ "n" }, "", ":lua Snacks.terminal.toggle()", { desc = "Toggle Terminal" }) 223 | km.set({ "t" }, "", exitTerm) 224 | 225 | -- km.set("n", "l", ":LazyGit", { silent = true, desc = "Lazygit" }) 226 | km.set("n", "l", ":lua Snacks.lazygit.open()", { silent = true, desc = "Lazygit" }) 227 | 228 | -- Easy delete buffer without losing window split 229 | km.set("n", "d", ":lua Snacks.bufdelete.delete()", { silent = true, desc = "Buffer Delete" }) 230 | 231 | -- Zen Mode 232 | Snacks.toggle.zen():map("z") 233 | 234 | -- Show Notifier history 235 | km.set("n", "xh", ":lua Snacks.notifier.show_history()", { silent = true, desc = "Notifier history" }) 236 | 237 | km.set("n", "gf", ":! git checkout -- % ", { silent = true, desc = "Chechout current file" }) 238 | --------------------------------------------------------------------------------