diff --git a/neovim/lua/_bindings.lua b/neovim/lua/_bindings.lua index f0b5b0c..a7a7532 100644 --- a/neovim/lua/_bindings.lua +++ b/neovim/lua/_bindings.lua @@ -8,6 +8,7 @@ map("n", "", ":set invnumber", opt_silent) map("n", "ln", ":set invnumber", opt_silent) map("n", "/", ":set hlsearch! hlsearch?", opt_silent) map("n", "cs", ":nohlsearch", opt_silent) +map("n", "ws", ":set list!", opt_silent) -- Save and quit typos map("c", "WQ", "wq", opt_silent) @@ -39,3 +40,17 @@ map("n", "U", ":redo", opt_default) map("i", "jk", "", opt_default) map("i", "``", "", opt_default) map("v", "``", "", opt_default) + +-- C-Space completion +_G.complete_space = function() + if vim.fn.pumvisible() == 1 then + return utils.t"" + elseif packer_plugins["completion-nvim"] and packer_plugins["completion-nvim"].loaded then + return utils.t"(completion_trigger)" + elseif packer_plugins["nvim-compe"] and packer_plugins["nvim-compe"].loaded then + return vim.fn["compe#complete"]() + else + return utils.t"" + end +end +map("i", "", "v:lua.complete_space()", {expr = true}) diff --git a/neovim/lua/init.lua b/neovim/lua/init.lua index 94b02bb..7a0eb83 100644 --- a/neovim/lua/init.lua +++ b/neovim/lua/init.lua @@ -36,29 +36,37 @@ _G.update_colors = function() local default_color = "solarized" local env_color = utils.env_default("VIM_COLOR", default_color) - -- Set background from dark mode - local darkmode = vim.env.IS_DARKMODE + -- Read dark mode + local mode = vim.env.IS_DARKMODE if vim.g.is_mac == 1 then cmd = "defaults read -g AppleInterfaceStyle 2>/dev/null || echo Light" - darkmode = vim.fn.system(cmd):gsub("\n", ""):lower() + mode = vim.fn.system(cmd):gsub("\n", ""):lower() end + -- Update background and theme local change = false - if darkmode == "dark" then + if mode == "dark" then env_color = utils.env_default("VIM_COLOR_DARK", env_color) change = maybe_set("o", "background", "dark") change = maybe_set("g", "colors_name", env_color) or change - elseif darkmode == "light" then + elseif mode == "light" then env_color = utils.env_default("VIM_COLOR_LIGHT", env_color) change = maybe_set("o", "background", "light") change = maybe_set("g", "colors_name", env_color) or change end + -- Update status line theme if change and vim.fn.exists(":AirlineRefresh") == 1 then vim.cmd(":AirlineRefresh") + elseif change and _G["packer_plugins"] ~= nil and packer_plugins["lualine"] and packer_plugins["lualine"].loaded then + local lualine_theme = vim.g.colors_name + if lualine_theme == "solarized" then + lualine_theme = lualine_theme .. "_" .. mode + end + require("plugins.lualine").config_lualine(lualine_theme) end - return changed and "Changed color to " .. env_color .. " with mode " .. darkmode or "No change" + return changed and "Changed color to " .. env_color .. " with mode " .. mode or "No change" end -- utils.autocmd("auto_colors", "FocusGained * call v:lua.update_colors()") diff --git a/neovim/lua/plugins.lua b/neovim/lua/plugins.lua index 19f5df1..c7b7158 100644 --- a/neovim/lua/plugins.lua +++ b/neovim/lua/plugins.lua @@ -10,129 +10,6 @@ end -- Requires :PackerCompile for "config" to be loaded -local function config_ts() - require'nvim-treesitter.configs'.setup{ - incremental_selection = { enable = true }, - -- Indent appears to be broken right now - indent = { enable = false }, - textobjects = { enable = true }, - highlight = { - enable = true, - disable = {}, - }, - ensure_installed = { - "bash", - "css", - "fish", - "go", - "gomod", - "javascript", - "json", - "lua", - "python", - "rust", - "yaml", - }, - } -end - -_G.complete_space = function() - if vim.fn.pumvisible() == 1 then - return utils.t"" - else - -- TODO: Switch if using compe - return utils.t"(completion_trigger)" - -- return vim.fn["compe#complete"]() - end -end - --- TODO: Determine if keeping this -local function config_compe() - require("compe").setup{ - enabled = true, - autocomplete = true, - source = { - path = true, - buffer = true, - calc = true, - tags = true, - spell = true, - nvim_lsp = true, - nvim_lua = true, - }, - } -end - --- TODO: Some issue with tags completion maybe compe is better? -local function config_complete() - vim.o.completeopt = "menuone,noinsert,noselect" - -- shortmess+=c - vim.g.completion_enable_auto_popup = 0 - -- vim.api.nvim_set_keymap("i", "", "(completion_trigger)", {silent=true}) - vim.api.nvim_set_keymap("i", "", "v:lua.complete_space()", {expr = true}) - vim.g.completion_enable_auto_paren = 1 - vim.cmd([[ - augroup completionPlugin - autocmd BufEnter * lua require('completion').on_attach() - augroup end - ]]) -end - --- TODO: Determine if I want to keep this or fzf -local function config_telescope() - local actions = require("telescope.actions") - require("telescope").setup{ - defaults = { - vimgrep_arguments = { - "rg", - "--color=never", - "--no-heading", - "--with-filename", - "--line-number", - "--column", - "--smart-case", - }, - mappings = { - i = { - [""] = actions.close, - } - } - } - } - opts = {silent=true, noremap=true} - vim.api.nvim_set_keymap("n", "", "Telescope find_files", opts) - vim.api.nvim_set_keymap("n", "ff", "Telescope find_files", opts) - vim.api.nvim_set_keymap("n", "fh", "Telescope help_tags", opts) - vim.api.nvim_set_keymap("n", "b", "Telescope buffers", opts) - vim.api.nvim_set_keymap("n", "t", "Telescope current_buffer_tags", opts) - vim.api.nvim_set_keymap("n", "ft", "Telescope tags", opts) -end - --- TODO: Customize mode to one letter and maybe not export as global -function config_lualine(theme_name) - if theme_name == "wombat256mod" then - theme_name = "wombat" - end - require("lualine").setup { - options = { - theme = theme_name, - icons_enabled = false, - component_separators = {"|", "|"}, - section_separators = {" ", " "}, - }, - sections = { - lualine_a = { { "mode", lower = false } }, - lualine_b = { "branch", "diff" }, - lualine_c = { "filename" }, - lualine_x = { "encoding", "fileformat", "filetype" }, - lualine_y = { "progress", "location" }, - lualine_z = { - { "diagnostics", sources = { "nvim_lsp" } }, - }, - }, - } -end - -- TODO: Get rid of if airline goes local function config_airline() -- Use short-form mode text @@ -168,8 +45,10 @@ local function config_airline() vim.g["airline#parts#ffenc#skip_expected_string"] = "utf-8[unix]" -- If UTF-8 symbols don't work, use ASCII -- vim.g.airline_symbols_ascii = 1 + vim.g["airline#extensions#nvimlsp#enabled"] = 1 end +-- Configures dark-notify to use colors from my environment local function config_dark_notify() local default_color = "solarized" local env_color = utils.env_default("VIM_COLOR", default_color) @@ -179,11 +58,12 @@ local function config_dark_notify() light = utils.env_default("VIM_COLOR_LIGHT", env_color), }, onchange = function(mode) + -- Update lualine with new colors local lualine_theme = vim.g.colors_name if lualine_theme == "solarized" then lualine_theme = lualine_theme .. "_" .. mode end - config_lualine(lualine_theme) + require("plugins.lualine").config_lualine(lualine_theme) end, } end @@ -217,6 +97,13 @@ return require('packer').startup(function() "tpope/vim-fugitive", cmd = { "Git", "Gstatus", "Gblame", "Gpush", "Gpull" }, } + use { + "milkypostman/vim-togglelist", + config = function() + vim.api.nvim_set_keymap("n", "", ":call ToggleQuickfixList()", {silent=true, noremap=true}) + vim.api.nvim_set_keymap("n", "", ":call ToggleLocationList()", {silent=true, noremap=true}) + end, + } -- UI use "vim-scripts/wombat256.vim" @@ -245,7 +132,7 @@ return require('packer').startup(function() use { "hoob3rt/lualine.nvim", -- configured by dark-notify - -- config = function() config_lualine("auto") end, + -- config = function() require("plugins.lualine").config_lualine("solarized") end, } use { "cormacrelf/dark-notify", @@ -256,21 +143,13 @@ return require('packer').startup(function() } use { 'mhinz/vim-startify', - config = function() - vim.g.startify_list_order = { - { ' My Bookmarks'}, 'bookmarks', - { ' Most recently used files in the current directory' }, 'dir', - { ' Most recently used files' }, 'files', - { ' My Sessions' }, 'sessions' - } - require("utils").maybe_require("plugins.startify_local") - end, + config = function() require("utils").require_with_local("plugins.startify") end, } -- LSP use { "neovim/nvim-lspconfig", - config = function() require("plugins.lsp").config_lsp() end, + config = function() require("utils").require_with_local("plugins.lsp") end, } use { "glepnir/lspsaga.nvim", @@ -281,7 +160,7 @@ return require('packer').startup(function() use { "nvim-treesitter/nvim-treesitter", run = ":TSUpdate", - config = config_ts, + config = function() require("utils").require_with_local("plugins.treesitter") end, } use { "nvim-treesitter/nvim-treesitter-refactor", @@ -301,17 +180,52 @@ return require('packer').startup(function() -- Completion use { "nvim-lua/completion-nvim", - config = config_complete, + config = function() require("utils").require_with_local("plugins.completion") end, } -- Fuzzy Finder use { "nvim-telescope/telescope.nvim", requires = { - "nvim-lua/popup.nvim", "nvim-lua/plenary.nvim", }, - config = config_telescope, + config = function() require("plugins.telescope") end, + } + use { + 'junegunn/fzf', + run = ":call fzf#install()", + } + use { + 'junegunn/fzf.vim', + requires = "junegunn/fzf", + config = function() + vim.g.fzf_command_prefix = 'FZF' + -- Jump to existing window if possible + vim.g.fzf_buffers_jump = 1 + -- Override key commands + -- vim.g.fzf_action = { ['ctrl-t'] = 'tab split', ['ctrl-s'] = 'split', ['ctrl-v'] = 'vsplit', } + -- Override git log to show authors + vim.g.fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h %an: %s%d %C(black)%C(bold)%cr"' + + vim.g.fzf_preview_window = {"right:50%", "ctrl-/"} + + vim.api.nvim_set_keymap("n", "", "FZF", {silent=true, noremap=true}) + vim.api.nvim_set_keymap("n", "b", "FZFBuffers", {silent=true, noremap=true}) + vim.api.nvim_set_keymap("n", "", "FZFBuffers", {silent=true, noremap=true}) + vim.api.nvim_set_keymap("n", "fg", "FZFRg", {silent=true, noremap=true}) + vim.api.nvim_set_keymap("n", "r", "FZFTags", {silent=true, noremap=true}) + vim.api.nvim_set_keymap("n", "t", "FZFBTags", {silent=true, noremap=true}) + vim.api.nvim_set_keymap("n", "g", "FZFBCommits", {silent=true, noremap=true}) + end, + } + use { + "ojroques/nvim-lspfuzzy", + requires = { "junegunn/fzf", "junegunn/fzf" }, + config = function() + require("lspfuzzy").setup{ + fzf_trim = false, + } + end, } -- Filetypes diff --git a/neovim/lua/plugins/completion.lua b/neovim/lua/plugins/completion.lua new file mode 100644 index 0000000..6e50f63 --- /dev/null +++ b/neovim/lua/plugins/completion.lua @@ -0,0 +1,32 @@ +-- TODO: Determine if keeping this +local function config_compe() + require("compe").setup{ + enabled = true, + autocomplete = true, + source = { + path = true, + buffer = true, + calc = true, + tags = true, + spell = true, + nvim_lsp = true, + nvim_lua = true, + }, + } +end + +-- TODO: Some issue with tags completion maybe compe is better? +local function config_complete() + vim.o.completeopt = "menuone,noinsert,noselect" + -- shortmess+=c + vim.g.completion_enable_auto_popup = 0 + -- vim.api.nvim_set_keymap("i", "", "(completion_trigger)", {silent=true}) + vim.g.completion_enable_auto_paren = 1 + vim.cmd([[ + augroup completionPlugin + autocmd BufEnter * lua require('completion').on_attach() + augroup end + ]]) +end + +config_complete() diff --git a/neovim/lua/plugins/lsp.lua b/neovim/lua/plugins/lsp.lua index 3493310..0e4a88c 100644 --- a/neovim/lua/plugins/lsp.lua +++ b/neovim/lua/plugins/lsp.lua @@ -1,5 +1,3 @@ -local M = {} - local function default_attach(client, bufnr) require('completion').on_attach() @@ -55,11 +53,15 @@ local function default_attach(client, bufnr) end -- Some override telescope bindings - buf_set_keymap("n", "t", "Telescope lsp_document_symbols", opts) - buf_set_keymap("n", "ft", "Telescope lsp_dynamic_workspace_symbols", opts) + -- TODO: Detect telescope or nvim-lspfuzzy and set keymap accordingly + buf_set_keymap("n", "t", "lua vim.lsp.buf.document_symbol()", opts) + -- buf_set_keymap("n", "ft", "lua vim.lsp.buf.workspace_symbol()", opts) + + -- buf_set_keymap("n", "t", "Telescope lsp_document_symbols", opts) + -- buf_set_keymap("n", "ft", "Telescope lsp_dynamic_workspace_symbols", opts) end -function M.config_lsp() +local function config_lsp() local language_servers = { "bashls", "gopls", @@ -82,4 +84,4 @@ function M.config_lsp() end end -return M +config_lsp() diff --git a/neovim/lua/plugins/lualine.lua b/neovim/lua/plugins/lualine.lua new file mode 100644 index 0000000..36319c4 --- /dev/null +++ b/neovim/lua/plugins/lualine.lua @@ -0,0 +1,87 @@ +local M = {} + +-- Only return interesting ffenc (not utf-8[unix]) +function M.custom_ffenc() + local enc = vim.bo.fenc + local format = vim.bo.fileformat + if enc ~= "utf-8" or format ~= "unix" then + return enc .. "[" .. format .. "]" + end + + return nil +end + +-- Use only single letters for mode names +function M.single_letter_mode() + local mode_map = { + ['__'] = '-', + ['n'] = 'N', + ['i'] = 'I', + ['R'] = 'R', + ['c'] = 'C', + ['v'] = 'V', + ['V'] = 'V', + [''] = 'V', + ['s'] = 'S', + ['S'] = 'S', + [''] = 'S', + ['t'] = 'T', + } + + return mode_map[vim.fn.mode()] +end + +function M.mixed_indent() + local mixed = vim.fn.search([[\v^(\t+ | +\t)]], 'nw') + if mixed > 0 then + return "i:" .. mixed + end + local space_indent = vim.fn.search([[\v^ +]], 'nw') + local tab_indent = vim.fn.search([[\v^\t+]], 'nw') + if tab_indent > 0 and space_indent > 0 then + return "i:" .. require("math").max(tab_indent, space_indent) + end + + return nil +end + +function M.trailing_whitespace() + local count = vim.fn.search([[\s\+$]], 'nw') + if count ~= 0 then + return "tw:" .. count + end + + return nil +end + +-- Configure lualine witha provided theme +function M.config_lualine(theme_name) + if theme_name == nil then + theme_name = "auto" + elseif theme_name == "wombat256mod" then + theme_name = "wombat" + end + + + require("lualine").setup { + options = { + theme = theme_name, + icons_enabled = false, + component_separators = {"|", "|"}, + section_separators = {" ", " "}, + }, + sections = { + lualine_a = { M.single_letter_mode }, + lualine_b = { "branch", "diff" }, + lualine_c = { "filename" }, + lualine_x = { M.custom_ffenc, "filetype" }, + lualine_y = { "progress", "location" }, + lualine_z = { + { "diagnostics", sources = { "nvim_lsp" } }, + M.mixed_indent, M.trailing_whitespace, + }, + }, + } +end + +return M diff --git a/neovim/lua/plugins/startify.lua b/neovim/lua/plugins/startify.lua new file mode 100644 index 0000000..9cfe7dc --- /dev/null +++ b/neovim/lua/plugins/startify.lua @@ -0,0 +1,6 @@ +vim.g.startify_list_order = { + { ' My Bookmarks'}, 'bookmarks', + { ' Most recently used files in the current directory' }, 'dir', + { ' Most recently used files' }, 'files', + { ' My Sessions' }, 'sessions' +} diff --git a/neovim/lua/plugins/telescope.lua b/neovim/lua/plugins/telescope.lua new file mode 100644 index 0000000..4901b43 --- /dev/null +++ b/neovim/lua/plugins/telescope.lua @@ -0,0 +1,35 @@ +local function config_telescope() + local actions = require("telescope.actions") + require("telescope").setup{ + defaults = { + vimgrep_arguments = { + "rg", + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + "--smart-case", + }, + mappings = { + i = { + [""] = actions.close, + -- Disable scroll-up to allow clearing prompt + [""] = false, + } + }, + layout_strategy = "flex", + } + } + opts = {silent=true, noremap=true} + vim.api.nvim_set_keymap("n", "", "Telescope find_files", opts) + vim.api.nvim_set_keymap("n", "ff", "Telescope find_files", opts) + vim.api.nvim_set_keymap("n", "fh", "Telescope help_tags", opts) + vim.api.nvim_set_keymap("n", "b", "Telescope buffers", opts) + vim.api.nvim_set_keymap("n", "fb", "Telescope buffers", opts) + vim.api.nvim_set_keymap("n", "t", "Telescope current_buffer_tags", opts) + vim.api.nvim_set_keymap("n", "ft", "Telescope tags", opts) + vim.api.nvim_set_keymap("n", "fg", "Telescope live_grep", opts) +end + +config_telescope() diff --git a/neovim/lua/plugins/treesitter.lua b/neovim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..db8a231 --- /dev/null +++ b/neovim/lua/plugins/treesitter.lua @@ -0,0 +1,24 @@ +-- Configures nvim-treesitter +require'nvim-treesitter.configs'.setup{ + incremental_selection = { enable = true }, + -- Indent appears to be broken right now + indent = { enable = false }, + textobjects = { enable = true }, + highlight = { + enable = true, + disable = {}, + }, + ensure_installed = { + "bash", + "css", + "fish", + "go", + "gomod", + "javascript", + "json", + "lua", + "python", + "rust", + "yaml", + }, +} diff --git a/neovim/lua/utils.lua b/neovim/lua/utils.lua index 3de72b0..396fb51 100644 --- a/neovim/lua/utils.lua +++ b/neovim/lua/utils.lua @@ -76,8 +76,17 @@ end -- Require a package and a "_local" suffixed one function M.require_with_local(name) - require(name) - M.maybe_require(name .. "_local") + -- TODO: Decide if local should completely override the versioned module + -- In that case, the local file would probably start with a `require` for the + -- non-local version. This would allow more control but at the cost of a bit + -- of boiler plate + rmod = require(name) + lmod = M.maybe_require(name .. "_local") + if lmod ~= nil then + return lmod + end + + return rmod end return M