Skip to content

Instantly share code, notes, and snippets.

@qti3e
Last active August 27, 2023 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qti3e/91089b6f4436e194e092d40721c4b5da to your computer and use it in GitHub Desktop.
Save qti3e/91089b6f4436e194e092d40721c4b5da to your computer and use it in GitHub Desktop.
My neovim configuration
local o = vim.opt
local map = vim.keymap.set
local api = vim.api
local nvim_create_autocmd = api.nvim_create_autocmd
local nvim_create_augroup = api.nvim_create_augroup
-- =============================================================================
-- Global Options
-- =============================================================================
-- disable netrw at the very start of your init.lua (strongly advised)
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
-- Make sure to set `mapleader` before lazy so the mappings are correct
map('n', '<Space>', '', {})
vim.g.mapleader = ' '
-- Disable mouse.
o.mouse = ""
-- Disable arrow keys.
map("", "<up>", "<nop>", { noremap = true })
map("", "<down>", "<nop>", { noremap = true })
map("i", "<up>", "<nop>", { noremap = true })
map("i", "<down>", "<nop>", { noremap = true })
map("", "<left>", "<nop>", { noremap = true })
map("", "<right>", "<nop>", { noremap = true })
map("i", "<left>", "<nop>", { noremap = true })
map("i", "<right>", "<nop>", { noremap = true })
-- Set completeopt to have a better completion experience
-- :help completeopt
-- menuone: popup even when there's only one match
-- noinsert: Do not insert text until a selection is made
-- noselect: Do not auto-select, nvim-cmp plugin will handle this for us.
o.completeopt = "menuone,noinsert,noselect"
-- Avoid showing extra messages when using completion
o.shortmess = o.shortmess + "c"
-- Line number and tab size
vim.wo.number = true
o.relativenumber = true
o.expandtab = true
o.smartindent = true
o.tabstop = 2
o.shiftwidth = 2
o.list = true
o.cmdheight=0
-- o.listchars:append "space:⋅"
-- o.listchars:append "eol:↴"
-- Enable spell check
o.spell = true
o.spelllang = { "en_us" }
o.spelloptions = 'camel'
o.spellcapcheck = ""
-- Reserve the sign width so screen would not act crazy when it
-- sees the sign when it is placed.
nvim_create_autocmd({ "BufEnter" }, {
command = "set signcolumn=yes:1",
})
-- =============================================================================
-- KEY MAPPINGS
-- =============================================================================
map("n", "K", vim.lsp.buf.hover, { desc = "LSP Hover" })
map("n", "<c-k>", vim.lsp.buf.signature_help, {desc = "Sig Help" })
map("n", "ga", vim.lsp.buf.code_action, { desc = "Code Actions" })
map("n", "<leader>r", vim.lsp.buf.rename, { desc = "Rename" })
-- Goto previous/next diagnostic warning/error
map("n", "g[", vim.diagnostic.goto_prev, { desc = "Prev Diagnostic" })
map("n", "g]", vim.diagnostic.goto_next, { desc = "Next Diagnostic" })
-- Copy & Paste
map({'n', 'i', 'v'}, '<C-c>', '"*y', { desc = "Copy" })
map({'n', 'i', 'v'}, '<C-p>', '"*p', { desc = "Paste" })
-- =============================================================================
-- SETUP LAZY
-- =============================================================================
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
o.rtp:prepend(lazypath)
-- A set of buffer names that we don't want plugins to be enabled in.
local internal_filetypes = {
"Outline",
"NvimTree",
"Starter",
"NeogitStatus",
"lazy",
"Trouble",
"telescope",
"notify",
"cmp_menu",
"noice",
"flash_prompt",
}
-- =============================================================================
-- SETUP PLUGINS
-- =============================================================================
require("lazy").setup({
-- {
-- "Mofiqul/dracula.nvim",
-- -- priority = 1000,
-- opts = {
-- colors = {
-- bg = "#282A36",
-- fg = "#F8F8F2",
-- selection = "#44475A",
-- comment = "#6272A4",
-- red = "#FF5555",
-- orange = "#FFB86C",
-- yellow = "#F1FA8C",
-- green = "#50fa7b",
-- purple = "#BD93F9",
-- cyan = "#8BE9FD",
-- pink = "#FF79C6",
-- bright_red = "#FF6E6E",
-- bright_green = "#69FF94",
-- bright_yellow = "#FFFFA5",
-- bright_blue = "#D6ACFF",
-- bright_magenta = "#FF92DF",
-- bright_cyan = "#A4FFFF",
-- bright_white = "#FFFFFF",
-- menu = "#21222C",
-- visual = "#3E4452",
-- gutter_fg = "#4B5263",
-- nontext = "#3B4048",
-- white = "#ABB2BF",
-- black = "#191A21",
-- },
-- },
-- config = function(_, opts)
-- require("dracula").setup(opts)
-- -- vim.cmd("colorscheme kanagawa")
-- end
-- },
{
'projekt0n/github-nvim-theme',
lazy = false, -- make sure we load this during startup if it is your main colorscheme
priority = 1000, -- make sure to load this before all the other start plugins
config = function()
require('github-theme').setup({
-- ...
})
vim.cmd('colorscheme github_dark_high_contrast')
end,
},
-- ===========================================================================
-- Colorscheme
-- ===========================================================================
-- {
-- "rebelot/kanagawa.nvim",
-- priority = 1000,
-- lazy = false,
-- opts = {
-- compile = false, -- enable compiling the colorscheme
-- undercurl = true, -- enable undercurls
-- commentStyle = { italic = true },
-- functionStyle = {},
-- keywordStyle = { italic = true},
-- statementStyle = { bold = true },
-- typeStyle = {},
-- transparent = false, -- do not set background color
-- dimInactive = false, -- dim inactive window `:h hl-NormalNC`
-- terminalColors = true, -- define vim.g.terminal_color_{0,17}
-- colors = { -- add/modify theme and palette colors
-- palette = {},
-- theme = { wave = {}, lotus = {}, dragon = {}, all = {} },
-- },
-- overrides = function(colors) -- add/modify highlights
-- return {}
-- end,
-- theme = "wave", -- Load "wave" theme when 'background' option is not set
-- background = { -- map the value of 'background' option to a theme
-- dark = "wave", -- try "dragon" !
-- light = "lotus"
-- },
-- },
-- config = function(_, opts)
-- require("kanagawa").setup(opts)
-- vim.cmd("colorscheme kanagawa")
-- end
-- },
-- ===========================================================================
-- FILE TREE
-- ===========================================================================
{
"nvim-tree/nvim-tree.lua",
event = "VimEnter",
dependencies = { 'nvim-tree/nvim-web-devicons' },
opts = {
update_focused_file = {
enable = true,
},
sort_by = "relative_directory",
view = {
width = 30,
},
renderer = {
group_empty = true,
},
filters = {
dotfiles = false,
},
tab = {
sync = {
open = true,
close = true,
ignore = {},
},
},
},
keys = {
{
"<leader>t",
function()
require("nvim-tree.api").tree.toggle({
find_file = true,
update_root = true,
})
end,
desc = "Toggle file tree"
},
}
},
-- ===========================================================================
-- TABS AND FILE BUFFERS
-- ===========================================================================
{
'romgrk/barbar.nvim',
event = "VimEnter",
dependencies = {
'lewis6991/gitsigns.nvim', -- OPTIONAL: for git status
'nvim-tree/nvim-web-devicons', -- OPTIONAL: for file icons
},
version = '^1.0.0',
init = function() vim.g.barbar_auto_setup = true end,
opts = {
icons = {
visible = {button = ''},
current = {button = ''},
inactive = {button = ''},
}
},
keys = {
-- Magic buffer-picking mode
{ "Bp", "<CMD>BufferPick<CR>", silent = true, noremap = true},
-- Pin/unpin buffer
{ "Bi", "<CMD>BufferPin<CR>", silent = true, noremap = true},
-- Re-order to previous/next
{ "Bmh", "<CMD>BufferMovePrevious<CR>", silent = true, noremap = true},
{ "Bml", "<CMD>BufferMoveNext<CR>", silent = true, noremap = true},
-- Move to previous/next
{ "Bh", "<CMD>BufferPrevious<CR>", silent = true, noremap = true},
{ "Bl", "<CMD>BufferNext<CR>", silent = true, noremap = true},
-- Goto buffer in position...
{ "B1", "<CMD>BufferGoto 1<CR>", silent = true, noremap = true},
{ "B2", "<CMD>BufferGoto 2<CR>", silent = true, noremap = true},
{ "B3", "<CMD>BufferGoto 3<CR>", silent = true, noremap = true},
{ "B4", "<CMD>BufferGoto 4<CR>", silent = true, noremap = true},
{ "B5", "<CMD>BufferGoto 5<CR>", silent = true, noremap = true},
{ "B6", "<CMD>BufferGoto 6<CR>", silent = true, noremap = true},
{ "B7", "<CMD>BufferGoto 7<CR>", silent = true, noremap = true},
{ "B8", "<CMD>BufferGoto 8<CR>", silent = true, noremap = true},
{ "B9", "<CMD>BufferGoto 9<CR>", silent = true, noremap = true},
{ "B0", "<CMD>BufferLast<CR>", silent = true, noremap = true},
-- Close buffer
{ "Bc", "<CMD>BufferClose<CR>", silent = true, noremap = true},
{ "Bqa", "<CMD>BufferCloseAllButCurrentOrPinned<CR>", silent = true, noremap = true},
{ "Bqh", "<CMD>BufferCloseBuffersLeft<CR>", silent = true, noremap = true},
{ "Bql", "<CMD>BufferCloseBuffersRight<CR>", silent = true, noremap = true},
},
},
-- ===========================================================================
-- STATUS LINE
-- ===========================================================================
{
-- integrate with lualine
'nvim-lualine/lualine.nvim',
dependencies = {
'nvim-tree/nvim-web-devicons',
{
'linrongbin16/lsp-progress.nvim',
dependencies = { 'nvim-tree/nvim-web-devicons' },
config = function()
require('lsp-progress').setup()
end
},
},
config = function()
-- Force refresh when lsp progress is updated.
nvim_create_augroup("lualine_augroup", { clear = true })
nvim_create_autocmd("User LspProgressStatusUpdated", {
group = "lualine_augroup",
callback = require("lualine").refresh,
})
-- Force refresh when recording macro status changes
-- https://www.reddit.com/r/neovim/comments/xy0tu1/cmdheight0_recording_macros_message/
nvim_create_autocmd("RecordingEnter", {
callback = require("lualine").refresh,
})
nvim_create_autocmd("RecordingLeave", {
callback = function()
-- This is going to seem really weird!
-- Instead of just calling refresh we need to wait a moment because of the nature of
-- `vim.fn.reg_recording`. If we tell lualine to refresh right now it actually will
-- still show a recording occuring because `vim.fn.reg_recording` hasn't emptied yet.
-- So what we need to do is wait a tiny amount of time (in this instance 50 ms) to
-- ensure `vim.fn.reg_recording` is purged before asking lualine to refresh.
local timer = vim.loop.new_timer()
timer:start(
50,
0,
vim.schedule_wrap(require("lualine").refresh)
)
end,
})
local function show_macro_recording()
local recording_register = vim.fn.reg_recording()
if recording_register == "" then
return ""
else
return "Recording @" .. recording_register
end
end
local filename = {
'filename',
file_status = true, -- Displays file status (readonly status, modified status)
newfile_status = false, -- Display new file status (new file means no write after created)
-- 0: Just the filename
-- 1: Relative path
-- 2: Absolute path
-- 3: Absolute path, with tilde as the home directory
path = 1,
shorting_target = 40, -- Shortens path to leave 40 spaces in the window
-- for other components. (terrible name, any suggestions?)
symbols = {
modified = '[+]', -- Text to show when the file is modified.
readonly = '[-]', -- Text to show when the file is non-modifiable or readonly.
unnamed = '[No Name]', -- Text to show for unnamed buffers.
newfile = '[New]', -- Text to show for newly created file before first write
}
}
local sections = {
lualine_a = {
'mode',
{
"macro-recording",
fmt = show_macro_recording,
},
},
lualine_b = {'branch', 'diff', 'diagnostics'},
lualine_c = {
filename,
},
lualine_x = {
"require('lsp-progress').progress()",
},
lualine_y = {'progress'},
lualine_z = {'location'},
}
require('lualine').setup({
options = {
disabled_filetypes = internal_filetypes,
ignore_focus = internal_filetypes,
},
sections = sections,
winbar = {
lualine_a = {
'filetype',
},
lualine_c = {
{
"navic",
color_correction = nil,
navic_opts = nil
}
}
},
extensions = { 'nvim-tree' }
})
end
},
-- ===========================================================================
-- LSP CONFIG
-- ===========================================================================
{
"neovim/nvim-lspconfig",
dependencies = {
{
"lukas-reineke/lsp-format.nvim",
opts = {}
},
{
"lvimuser/lsp-inlayhints.nvim",
opts = {}
},
},
event = { "BufReadPost", "BufNewFile" },
cmd = { "LspInfo", "LspInstall", "LspUninstall" },
config = function()
local lspconfig = require('lspconfig')
lspconfig.rust_analyzer.setup {
-- Server-specific settings. See `:help lspconfig-setup`
settings = {
['rust-analyzer'] = {},
},
on_attach = function(client, bufnr)
require("lsp-format").on_attach(client)
require("lsp-inlayhints").on_attach(client, bufnr)
require("nvim-navic").attach(client, bufnr)
end
}
end
},
-- ===========================================================================
-- Trouble can show the diagnostics at the bottom.
-- ===========================================================================
{
"folke/trouble.nvim",
event = "LspAttach",
dependencies = { "nvim-tree/nvim-web-devicons" },
opts = {
-- your configuration comes here
-- or leave it empty to use the default settings
-- refer to the configuration section below
},
},
-- ===========================================================================
-- Code context breadcrumbs:
-- The setup of this plugin is a little involved.
-- 1. We have to make sure the on_attach callback on the lspconfig is setup
-- properly. So it activates this plugin.
-- 2. This plugin does *render* anything on its own. We are making it visible
-- by putting a section under the winbar in lualine.
-- ===========================================================================
{
"SmiteshP/nvim-navic",
event = { "BufReadPost", "BufNewFile" },
dependencies = {
"neovim/nvim-lspconfig",
},
opts = {}
},
-- ===========================================================================
-- Symbols Outline:
-- ===========================================================================
{
"simrat39/symbols-outline.nvim",
event = "LspAttach",
opts = {},
keys = {
{
"<leader>o",
"<CMD>SymbolsOutline<CR>",
desc = "Symbols Outline"
}
}
},
-- ===========================================================================
-- Auto complete for Cargo.toml files.
-- ===========================================================================
{
'saecki/crates.nvim',
event = { "BufRead Cargo.toml" },
requires = { { 'nvim-lua/plenary.nvim' } },
config = function()
require('crates').setup()
end,
},
-- ===========================================================================
-- Treesitter
-- ===========================================================================
{
'nvim-treesitter/nvim-treesitter',
build = function()
vim.cmd(":TSUpdate")
vim.cmd(":TSInstall markdown markdown_inline")
vim.cmd(":TSInstall rust")
end,
config = function ()
local configs = require("nvim-treesitter.configs")
configs.setup({
ensure_installed = {
"rust", "c", "lua", "vim", "vimdoc", "query",
"elixir", "heex", "javascript", "html"
},
sync_install = false,
highlight = { enable = true },
indent = { enable = true },
})
-- Use TreeSitter for folding
o.foldmethod = "expr"
o.foldexpr = "nvim_treesitter#foldexpr()"
o.foldlevel=3
end
},
-- ===========================================================================
-- Flash: Navigate your code with search labels, enhanced character motions
-- and Treesitter integration
-- ===========================================================================
{
"folke/flash.nvim",
event = "VeryLazy",
---@type Flash.Config
opts = {
search = {
exclude = internal_filetypes
},
},
-- stylua: ignore
keys = {
{ "s", mode = { "n", "x", "o" }, function() require("flash").jump() end, desc = "Flash" },
{ "S", mode = { "n", "o", "x" }, function() require("flash").treesitter() end, desc = "Flash Treesitter" },
{ "r", mode = "o", function() require("flash").remote() end, desc = "Remote Flash" },
{ "R", mode = { "o", "x" }, function() require("flash").treesitter_search() end, desc = "Treesitter Search" },
{ "<c-s>", mode = { "c" }, function() require("flash").toggle() end, desc = "Toggle Flash Search" },
{
"<leader>w",
function()
require("flash").jump({
pattern = ".", -- initialize pattern with any char
search = {
mode = function(pattern)
-- remove leading dot
if pattern:sub(1, 1) == "." then
pattern = pattern:sub(2)
end
-- return word pattern and proper skip pattern
return ([[\<%s\w*\>]]):format(pattern), ([[\<%s]]):format(pattern)
end,
},
-- select the range
jump = { pos = "range" },
})
end,
desc = "Select any word"
},
{
"<leader>g",
function()
require("flash").jump({
search = { mode = "search", max_length = 0 },
label = { after = { 0, 0 } },
pattern = "^"
})
end,
desc = "Goto a line"
},
},
},
-- ===========================================================================
-- Smoothie: Provides smooth scrolling experience.
-- ===========================================================================
{
"psliwka/vim-smoothie",
event = "VeryLazy",
},
-- ===========================================================================
-- Structural search and replace
-- ===========================================================================
{
"cshuaimin/ssr.nvim",
event = "VeryLazy",
opts = {
border = "rounded",
min_width = 50,
min_height = 5,
max_width = 120,
max_height = 25,
keymaps = {
close = "q",
next_match = "n",
prev_match = "N",
replace_confirm = "<cr>",
replace_all = "<leader><cr>",
},
},
keys = {
{
"<leader>sr",
function() require("ssr").open() end,
mode = { "n", "x" },
desc = "Structural search and replace"
}
}
},
-- ===========================================================================
-- Nice notifications
-- ===========================================================================
{
"rcarriga/nvim-notify",
event = "VimEnter",
config = function()
require("notify").setup({
background_colour = "#000000",
level = 2,
minimum_width = 30,
render = "compact",
stages = "fade_in_slide_out",
timeout = 5000,
top_down = true
})
-- So that other plugins can also use it as the default notify.
vim.notify = require("notify")
end
},
-- ===========================================================================
-- Git sign to show some git stats on each line
-- ===========================================================================
{
"lewis6991/gitsigns.nvim",
opts = {}
},
-- ===========================================================================
-- Show a light bulb when code actions are available.
-- ===========================================================================
{
'kosayoda/nvim-lightbulb',
event = "LspAttach",
opts = {
autocmd = { enabled = true }
}
},
-- ===========================================================================
-- Vim fetch enables vim to handle opening 'path.rs:102:10' at the right line
-- number.
-- ===========================================================================
{
"wsdjeg/vim-fetch",
lazy = false,
},
-- ===========================================================================
-- Let's share our work activity on discord.
-- ===========================================================================
{
'andweeb/presence.nvim',
event = "LspAttach",
opts = {
-- General options
-- The auto update slows down the switch between different buffers
-- so we disable it.
auto_update = false,
neovim_image_text = "The One True Text Editor",
main_image = "neovim",
client_id = "793271441293967371",
log_level = nil,
debounce_timeout = 10,
enable_line_number = false,
blacklist = internal_filetypes,
buttons = true,
file_assets = {},
show_time = true,
-- Rich Presence text options
editing_text = "🔪",
file_explorer_text = "Browsing %s",
git_commit_text = "Committing changes",
plugin_manager_text = "Managing plugins",
reading_text = "Reading %s",
workspace_text = "Working on %s",
line_number_text = "Line %s out of %s",
},
config = function(_, opts)
local presence = require("presence")
presence.setup(opts)
presence:update()
end
},
-- ===========================================================================
-- Show which key is doing what
-- ===========================================================================
{
"folke/which-key.nvim",
event = "VeryLazy",
init = function()
vim.o.timeout = true
vim.o.timeoutlen = 500
end,
opts = {
-- triggers_blacklist = {
-- -- list of mode / prefixes that should never be hooked by WhichKey
-- -- this is mostly relevant for keymaps that start with a native binding
-- i = { "j", "k" },
-- v = { "j", "k" },
-- },
}
},
-- ===========================================================================
-- Auto pair for []() and more...
-- ===========================================================================
{
'windwp/nvim-autopairs',
event = "InsertEnter",
config = function()
require("nvim-autopairs").setup({})
local autopairs = require("nvim-autopairs")
local Rule = require("nvim-autopairs.rule")
local cond = require("nvim-autopairs.conds")
autopairs.add_rules({
Rule("<", ">"):with_pair(cond.before_regex("%a+")):with_move(function(opts) return opts.char == ">" end),
})
end
},
-- ===========================================================================
-- TELESCOPE FUZZY FINDER
-- ===========================================================================
{
'nvim-telescope/telescope.nvim', tag = '0.1.2',
event = "BufEnter",
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-telescope/telescope-ui-select.nvim'
},
keys = {
{
"Bs",
function()
require('telescope.builtin').buffers()
end,
desc = "Show buffers"
},
{
"<C-f>",
function()
require('telescope.builtin').git_files()
end,
mode = {"n","i","v"},
desc = "Find Git Files"
},
{
"z=",
function()
require("telescope.builtin").spell_suggest(require("telescope.themes").get_cursor({}))
end,
mode = {"n","v"},
desc = "Spelling Suggestions"
},
{
"gr",
function()
require('telescope.builtin').lsp_references()
end,
mode = {"n","v"},
desc = "Find References"
},
{
"gD",
function()
require('telescope.builtin').lsp_document_symbols()
end,
mode = {"n","v"},
desc = "Document Symbols"
},
{
"gW",
function()
require('telescope.builtin').lsp_workspace_symbols()
end,
mode = {"n","v"},
desc = "Workspace Symbols"
},
{
"<leader>d",
function()
require('telescope.builtin').diagnostics({buffer = 0})
end,
mode = {"n", "v"},
desc = "Buffer diagnostics"
},
{
"<leader>D",
function()
require('telescope.builtin').diagnostics()
end,
mode = {"n", "v"},
desc = "Workspace diagnostics"
},
{
"gi",
function()
require('telescope.builtin').lsp_implementations()
end,
mode = {"n", "v"},
desc = "Goto implementation"
},
{
"gd",
function()
require('telescope.builtin').lsp_definitions()
end,
mode = {"n", "v"},
desc = "Goto definition"
},
{
"gt",
function()
require('telescope.builtin').lsp_type_definitions()
end,
mode = {"n", "v"},
desc = "Goto type definition"
},
},
opts = {
defaults = {
layout_strategy = 'vertical',
layout_config = { height = 0.95 },
},
},
config = function(_, opts)
-- FLASH INTEGRATION
local function flash(prompt_bufnr)
require("flash").jump({
pattern = "^",
label = { after = { 0, 0 } },
search = {
mode = "search",
exclude = {
function(win)
return vim.bo[vim.api.nvim_win_get_buf(win)].filetype ~= "TelescopeResults"
end,
},
},
action = function(match)
local picker = require("telescope.actions.state").get_current_picker(prompt_bufnr)
picker:set_selection(match.pos[1] - 1)
end,
})
end
opts.defaults = vim.tbl_deep_extend("force", opts.defaults or {}, {
mappings = {
n = { s = flash },
i = { ["<c-s>"] = flash },
},
})
-- END OF FLASH INTEGRATION >
opts.extensions = vim.tbl_deep_extend("force", opts.extensions or {}, {
["ui-select"] = {
require("telescope.themes").get_dropdown {
-- even more opts
}
}
})
require("telescope").setup(opts)
-- Load extensions
require("telescope").load_extension("ui-select")
end
},
-- ===========================================================================
-- SETUP AUTO COMPLETE
-- ===========================================================================
{
"hrsh7th/nvim-cmp",
event = "InsertEnter",
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-nvim-lsp-signature-help",
"neovim/nvim-lspconfig",
"hrsh7th/cmp-nvim-lua",
"hrsh7th/cmp-path",
"f3fora/cmp-spell",
"lukas-reineke/cmp-rg",
-- snippets
"L3MON4D3/LuaSnip",
{
"rafamadriz/friendly-snippets",
config = function()
require("luasnip.loaders.from_vscode").lazy_load()
end,
},
"saadparwaiz1/cmp_luasnip",
-- command line
"hrsh7th/cmp-cmdline",
"dmitmel/cmp-cmdline-history",
-- search
"hrsh7th/cmp-buffer",
-- vscode-like pictograms for neovim lsp completion items
"onsails/lspkind.nvim",
-- latex mathmatical symbols prefixed with `\`.
"kdheepak/cmp-latex-symbols",
-- emoji prefixed with `:`
"hrsh7th/cmp-emoji",
-- Just write some math thing.
"hrsh7th/cmp-calc",
},
config = function()
local cmp = require("cmp")
local luasnip = require("luasnip")
local lspkind = require("lspkind")
local has_words_before = function()
local line, col = unpack(api.nvim_win_get_cursor(0))
return col ~= 0
and api
.nvim_buf_get_lines(0, line - 1, line, true)[1]
:sub(col, col)
:match("%s")
== nil
end
local mapping = {
-- Use the jkl to move the completion and confirm.
-- For J/K always go up or down, this is different for when the popup is opened
-- from top to down or from down to top.
['<C-j>'] = function(fallback)
if cmp.visible() then
if cmp.core.view.custom_entries_view:is_direction_top_down() then
cmp.select_next_item()
else
cmp.select_prev_item()
end
else
fallback()
end
end,
['<C-k>'] = function(fallback)
if cmp.visible() then
if cmp.core.view.custom_entries_view:is_direction_top_down() then
cmp.select_prev_item()
else
cmp.select_next_item()
end
else
fallback()
end
end,
["<C-l>"] = cmp.mapping.confirm({
behavior = cmp.ConfirmBehavior.Insert,
select = true,
}),
["<C-u>"] = cmp.mapping.scroll_docs(-4),
["<C-d>"] = cmp.mapping.scroll_docs(4),
}
cmp.setup({
mapping = mapping,
completion = {
completeopt = "menu,menuone,noinsert",
},
sources = {
{ name = 'nvim_lsp' },
{ name = 'nvim_lsp_signature_help' },
{ name = "crates" },
{ name = "nvim_lua" },
{ name = "luasnip" },
{ name = "path" },
{ name = "rg", dup = 0 },
{ name = "spell", keyword_length = 4 },
{ name = "buffer" },
{ name = "calc" },
{ name = "emoji" },
{
name = "latex_symbols",
option = {
strategy = 0, -- mixed
},
},
},
snippet = {
expand = function(args)
require("luasnip").lsp_expand(args.body)
end,
},
window = {
completion = cmp.config.window.bordered({
col_offset = -3,
side_padding = 0,
winhighlight = "Normal:Normal,FloatBorder:Normal,CursorLine:Visual,Search:None",
}),
documentation = cmp.config.window.bordered({
winhighlight = "Normal:Normal,FloatBorder:Normal,CursorLine:Visual,Search:None",
}),
},
formatting = {
fields = { "kind", "abbr", "menu" },
format = function(entry, vim_item)
local kind = lspkind.cmp_format({
mode = "symbol_text",
maxwidth = 50,
})(entry, vim_item)
local strings = vim.split(kind.kind, "%s", { trimempty = true })
kind.kind = " " .. strings[1] .. " "
if strings[2] == nil then
kind.menu = " (-)"
else
kind.menu = " (" .. strings[2] .. ")"
end
return kind
end,
},
view = {
entries = { name = "custom", selection_order = "near_cursor" },
},
experimental = {
ghost_text = { hl_group = "LspInlayHint" },
},
})
local cmdline_mapping = {
-- Use the jkl to move the completion and confirm.
-- For J/K always go up or down, this is different for when the popup is opened
-- from top to down or from down to top.
['<C-j>'] = {
c = function(fallback)
if cmp.visible() then
if cmp.core.view.custom_entries_view:is_direction_top_down() then
cmp.select_next_item()
else
cmp.select_prev_item()
end
else
fallback()
end
end
},
['<C-k>'] = {
c = function(fallback)
if cmp.visible() then
if cmp.core.view.custom_entries_view:is_direction_top_down() then
cmp.select_prev_item()
else
cmp.select_next_item()
end
else
fallback()
end
end
},
["<C-l>"] = cmp.mapping.confirm({
behavior = cmp.ConfirmBehavior.Insert,
select = true,
}),
}
cmp.setup.cmdline(":", {
mapping = cmdline_mapping,
sources = {
{ name = "cmdline" },
{ name = "cmdline_history" },
{ name = "path" },
},
})
cmp.setup.cmdline({ "/", "?" }, {
mapping = cmdline_mapping,
sources = {
{ name = "buffer" },
},
})
end,
},
-- ===========================================================================
-- WakaTime integration for
-- ===========================================================================
{ "wakatime/vim-wakatime" },
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment