Skip to main content
Magictt provides a complete LSP setup with autocompletion, snippets, and code intelligence powered by nvim-cmp and nvim-lspconfig.

Overview

The LSP and completion system consists of:
  • nvim-lspconfig: LSP client configuration
  • mason.nvim: LSP server installation manager
  • nvim-cmp: Completion engine
  • LuaSnip: Snippet engine
  • Multiple completion sources: LSP, buffer, path, snippets
  • lspkind: VSCode-like completion icons

Completion Engine: nvim-cmp

nvim-cmp is the powerful autocompletion engine that provides intelligent suggestions as you type.

Features

  • Multiple Sources: Combines LSP, snippets, buffer text, and file paths
  • Smart Sorting: Prioritizes relevant completions
  • Preview: Shows documentation for completion items
  • Snippet Support: Expands and navigates snippets
  • LSP Integration: Full support for LSP capabilities

Completion Sources

Magictt uses these completion sources in priority order:
  1. nvim_lsp: Completions from language servers
  2. luasnip: Snippet completions
  3. buffer: Text from current buffer
  4. path: Filesystem paths

Keybindings

In Completion Menu

KeybindingAction
<C-k>Previous completion item
<C-j>Next completion item
<C-b>Scroll documentation up
<C-f>Scroll documentation down
<C-Space>Trigger completion manually
<C-e>Close completion menu
<CR>Confirm selected item

Completion Behavior

completion = {
  completeopt = "menu,menuone,preview,noselect",
}
  • menu: Show popup menu
  • menuone: Show menu even for single match
  • preview: Show preview window with documentation
  • noselect: Don’t auto-select first item

Configuration

Location: lua/magictt/plugins/nvim-cmp.lua
return {
  "hrsh7th/nvim-cmp",
  event = "InsertEnter",
  dependencies = {
    "hrsh7th/cmp-buffer",
    "hrsh7th/cmp-path",
    "L3MON4D3/LuaSnip",
    "saadparwaiz1/cmp_luasnip",
    "rafamadriz/friendly-snippets",
    "onsails/lspkind.nvim",
  },
  config = function()
    local cmp = require("cmp")
    local luasnip = require("luasnip")
    local lspkind = require("lspkind")

    -- Load VSCode-style snippets
    require("luasnip.loaders.from_vscode").lazy_load()

    cmp.setup({
      snippet = {
        expand = function(args)
          luasnip.lsp_expand(args.body)
        end,
      },
      mapping = cmp.mapping.preset.insert({
        ["<C-k>"] = cmp.mapping.select_prev_item(),
        ["<C-j>"] = cmp.mapping.select_next_item(),
        ["<C-b>"] = cmp.mapping.scroll_docs(-4),
        ["<C-f>"] = cmp.mapping.scroll_docs(4),
        ["<C-Space>"] = cmp.mapping.complete(),
        ["<C-e>"] = cmp.mapping.abort(),
        ["<CR>"] = cmp.mapping.confirm({ select = false }),
      }),
      sources = cmp.config.sources({
        { name = "nvim_lsp" },
        { name = "luasnip" },
        { name = "buffer" },
        { name = "path" },
      }),
      formatting = {
        format = lspkind.cmp_format({
          mode = "symbol_text",
        }),
      },
    })
  end,
}

Snippet Engine: LuaSnip

LuaSnip is a modern snippet engine that powers snippet expansion in completion.

Features

  • VSCode Snippets: Compatible with VSCode snippet format
  • Dynamic Snippets: Snippets can execute Lua code
  • Snippet Navigation: Tab through snippet placeholders
  • Friendly Snippets: Includes large snippet library

Snippet Sources

  • friendly-snippets: Community-maintained snippet collection
    • Snippets for 50+ languages
    • Common patterns and boilerplate
    • Framework-specific snippets (React, Vue, etc.)

Usage

  1. Start typing snippet trigger
  2. Snippet appears in completion menu
  3. Press <CR> to expand
  4. Tab through placeholders
  5. Finish editing snippet

Example Snippets

JavaScript/TypeScript:
  • logconsole.log()
  • clconsole.log()
  • fn → function declaration
  • afn → arrow function
  • imp → import statement
Python:
  • def → function definition
  • class → class definition
  • if → if statement
  • for → for loop
HTML:
  • ! → HTML5 boilerplate
  • div<div></div>
  • link<link> tag

Completion Icons: lspkind

lspkind adds VSCode-like pictograms to completion items, making it easy to identify item types.

Icon Types

  • 󰊕 Method
  • 󰆧 Function
  • 󰀫 Variable
  • Class
  • ⌘ Keyword
  • Snippet
  • File
  • Folder

Format

Magictt uses symbol_text mode:
󰊕 methodName (method)
 myVariable (variable)

Completion Sources

LSP Source (cmp-nvim-lsp)

Provides completions from language servers:
  • Function and method names
  • Variable names
  • Class and interface names
  • Keywords
  • Import suggestions

Buffer Source (cmp-buffer)

Provides completions from text in the current buffer:
  • Words you’ve already typed
  • Variable names in current file
  • Useful when LSP isn’t available

Path Source (cmp-path)

Provides filesystem path completions:
  • File paths
  • Directory paths
  • Relative and absolute paths

Snippet Source (cmp_luasnip)

Provides snippet completions:
  • Pre-defined snippets
  • Custom snippets
  • Framework-specific patterns

LSP Configuration: nvim-lspconfig

nvim-lspconfig provides configurations for Neovim’s built-in LSP client.

Features

  • Go to Definition: Jump to symbol definitions
  • Find References: Find all references to a symbol
  • Hover Documentation: Show documentation for symbol under cursor
  • Code Actions: Quick fixes and refactorings
  • Diagnostics: Real-time error and warning detection
  • Auto-format: Format code on save

Auto-format on Save

Magictt auto-formats JavaScript and TypeScript files:
vim.api.nvim_create_autocmd("BufWritePre", {
  pattern = { "*.js", "*.ts" },
  callback = function()
    vim.lsp.buf.format({ async = true })
  end,
})

Configuration

Location: lua/magictt/plugins/lsp/lsp.lua
return {
  {
    "hrsh7th/cmp-nvim-lsp",
    event = { "BufReadPre", "BufNewFile" },
    dependencies = {
      { "antosha417/nvim-lsp-file-operations", config = true },
      { "folke/lazydev.nvim", opts = {} },
      { "neovim/nvim-lspconfig" },
    },
    config = function()
      local cmp_nvim_lsp = require("cmp_nvim_lsp")
      
      -- Enable autocompletion for LSP
      local capabilities = cmp_nvim_lsp.default_capabilities()
      
      -- Auto-format on save
      vim.api.nvim_create_autocmd("BufWritePre", {
        pattern = { "*.js", "*.ts" },
        callback = function()
          vim.lsp.buf.format({ async = true })
        end,
      })
    end,
  },
}

Package Manager: mason.nvim

mason.nvim is a portable package manager for LSP servers, formatters, and linters.

Features

  • Easy Installation: Install servers with simple commands
  • Cross-platform: Works on Windows, macOS, and Linux
  • Auto-install: Can automatically install configured servers
  • Version Management: Install specific versions of tools

UI Commands

CommandAction
:MasonOpen Mason UI
:MasonUpdateUpdate registry
:MasonInstall <package>Install a package
:MasonUninstall <package>Uninstall a package

UI Icons

  • ✓ Package installed
  • ➜ Package pending installation
  • ✗ Package not installed

Configuration

Location: lua/magictt/plugins/lsp/mason.lua
return {
  {
    "williamboman/mason.nvim",
    opts = {
      ui = {
        icons = {
          package_installed = "✓",
          package_pending = "➜",
          package_uninstalled = "✗",
        },
      },
    },
  },
}

Mason LSP Config: mason-lspconfig.nvim

mason-lspconfig bridges mason.nvim with nvim-lspconfig for seamless server setup.

Auto-installed Servers

Magictt automatically installs these language servers:
ServerLanguage
ts_lsTypeScript/JavaScript
htmlHTML
csslsCSS
tailwindcssTailwind CSS
svelteSvelte
lua_lsLua
graphqlGraphQL
emmet_lsEmmet (HTML/CSS expansion)
prismalsPrisma ORM
pyrightPython
eslintESLint (JavaScript linting)

Configuration

return {
  {
    "williamboman/mason-lspconfig.nvim",
    opts = {
      ensure_installed = {
        "ts_ls",
        "html",
        "cssls",
        "tailwindcss",
        "svelte",
        "lua_ls",
        "graphql",
        "emmet_ls",
        "prismals",
        "pyright",
        "eslint",
      },
    },
  },
}

Mason Tool Installer: mason-tool-installer.nvim

mason-tool-installer automatically installs formatters and linters.

Auto-installed Tools

ToolPurpose
prettierFormatter for JS/TS/HTML/CSS/JSON
styluaLua formatter
isortPython import sorter
blackPython formatter
pylintPython linter
eslint_dFast ESLint daemon

Configuration

return {
  {
    "WhoIsSethDaniel/mason-tool-installer.nvim",
    opts = {
      ensure_installed = {
        "prettier",
        "stylua",
        "isort",
        "black",
        "pylint",
        "eslint_d",
      },
    },
  },
}

Additional LSP Features

LSP File Operations

nvim-lsp-file-operations notifies LSP servers when files are renamed or moved in nvim-tree.
  • Auto-updates imports when files move
  • Keeps project references in sync
  • Works seamlessly with nvim-tree

Lua Development: lazydev.nvim

lazydev.nvim provides better Lua development for Neovim configuration.
  • Neovim API completions
  • Plugin API completions
  • Better type checking for Neovim Lua

How Completion Works

The Flow

  1. Type in Insert Mode
    • nvim-cmp monitors your typing
  2. Sources Queried
    • LSP asked for completions
    • LuaSnip checks for matching snippets
    • Buffer scanned for matching text
    • Filesystem checked for path completions
  3. Results Combined
    • All sources return their results
    • Results ranked by relevance
    • Icons added by lspkind
  4. Menu Displayed
    • Completion menu appears
    • Navigate with <C-j> / <C-k>
    • Documentation shown in preview window
  5. Completion Confirmed
    • Press <CR> to confirm
    • Text inserted at cursor
    • If snippet, placeholders activated

Keybindings Summary

Completion

KeybindingAction
<C-Space>Trigger completion
<C-j>Next item
<C-k>Previous item
<C-f>Scroll docs down
<C-b>Scroll docs up
<CR>Confirm selection
<C-e>Close menu

LSP (defined elsewhere)

KeybindingAction
gdGo to definition
grGo to references
KHover documentation
<leader>caCode actions
<leader>rnRename symbol

Troubleshooting

Completion Not Working

  1. Check LSP is attached: :LspInfo
  2. Check sources are configured: :CmpStatus
  3. Verify server is installed: :Mason

Missing Snippets

  1. Ensure friendly-snippets is installed
  2. Check LuaSnip loaded: :lua print(require('luasnip').get_snippets())

Server Not Starting

  1. Open Mason: :Mason
  2. Install server if missing
  3. Check logs: :LspLog

Customization

Add More LSP Servers

Edit lua/magictt/plugins/lsp/mason.lua:
ensure_installed = {
  "ts_ls",
  "rust_analyzer",  -- Add Rust
  "gopls",          -- Add Go
  -- ... more servers
}

Change Completion Keybindings

Edit lua/magictt/plugins/nvim-cmp.lua:
mapping = cmp.mapping.preset.insert({
  ["<Tab>"] = cmp.mapping.select_next_item(),  -- Use Tab
  ["<S-Tab>"] = cmp.mapping.select_prev_item(), -- Use Shift-Tab
  -- ... customize more
})

Add Custom Snippets

Create ~/.config/nvim/snippets/<filetype>.json:
{
  "console.log": {
    "prefix": "cl",
    "body": ["console.log($1);"],
    "description": "Console log"
  }
}

Plugin Overview

See all installed plugins

Keybindings

Complete keybinding reference

Build docs developers (and LLMs) love