Skip to main content
Magictt uses the Language Server Protocol (LSP) to provide intelligent code features like autocompletion, go-to-definition, diagnostics, and more. The LSP configuration is managed across several files.

Architecture Overview

Magictt’s LSP setup uses three main components:
1

Mason

Package manager for installing language servers and formatters
2

mason-lspconfig

Bridge between Mason and nvim-lspconfig for automatic setup
3

nvim-lspconfig

Configures and launches language servers with keybindings

LSP Server Installation

Automatic Installation with Mason

Language servers are automatically installed via Mason. The configuration is in lua/magictt/plugins/lsp/mason.lua:
ensure_installed = {
  "ts_ls",        -- TypeScript/JavaScript
  "html",         -- HTML
  "cssls",        -- CSS
  "tailwindcss",  -- Tailwind CSS
  "svelte",       -- Svelte
  "lua_ls",       -- Lua
  "graphql",      -- GraphQL
  "emmet_ls",     -- Emmet
  "prismals",     -- Prisma
  "pyright",      -- Python
  "eslint",       -- ESLint
}
These servers will be automatically downloaded and installed when you first launch Neovim.

Mason UI Configuration

Mason’s UI uses custom icons for package status:
ui = {
  icons = {
    package_installed = "✓",
    package_pending = "➜",
    package_uninstalled = "✗",
  },
}
Opening Mason:
  • Use <leader>mm to open the Mason UI
  • View all installed and available packages
  • Manually install/uninstall packages as needed

LSP Keybindings

LSP keybindings are automatically configured when a language server attaches to a buffer. This is handled in lua/magictt/lsp.lua using an autocommand:
vim.api.nvim_create_autocmd("LspAttach", {
  group = vim.api.nvim_create_augroup("UserLspConfig", {}),
  callback = function(ev)
    -- Keybindings are set here when LSP attaches
  end,
})

Available LSP Keybindings

See the Keymaps page for a complete list of LSP keybindings. Quick reference:
  • gd - Go to definition
  • K - Show documentation
  • <leader>ca - Code actions
  • <leader>rn - Rename symbol
  • [d / ]d - Navigate diagnostics

Diagnostic Configuration

Diagnostic Display

Diagnostics (errors, warnings, hints) are configured in two places: Basic configuration (lua/magictt/core/options.lua):
vim.diagnostic.config({
  virtual_text = {
    prefix = "●",
    spacing = 4,
  },
  signs = true,
  underline = true,
  update_in_insert = false,
  severity_sort = true,
})
Diagnostic signs/icons (lua/magictt/lsp.lua):
local severity = vim.diagnostic.severity

vim.diagnostic.config({
  signs = {
    text = {
      [severity.ERROR] = " ",
      [severity.WARN] = " ",
      [severity.HINT] = "󰠠 ",
      [severity.INFO] = " ",
    },
  },
})

Diagnostic Features

Diagnostic messages appear inline at the end of problematic lines with a bullet (●) prefix and 4-space padding.
Icons appear in the sign column (left gutter) indicating the severity:
  • Error (red)
  • Warning (yellow)
  • Hint (blue)
  • Info (cyan)
Problematic code is underlined to make it easy to spot issues.
Diagnostics are sorted by severity, with errors appearing first.

Auto-Format on Save

Magictt uses conform.nvim for automatic formatting on save. Configuration is in lua/magictt/plugins/conform.lua.

Formatters Installation

Formatters are automatically installed via mason-tool-installer:
ensure_installed = {
  "prettier",  -- JavaScript, TypeScript, HTML, CSS, JSON
  "stylua",    -- Lua
  "isort",     -- Python imports
  "black",     -- Python
  "pylint",    -- Python linting
  "eslint_d",  -- JavaScript/TypeScript linting
}

Formatter Configuration

Formatters are configured per file type:
formatters_by_ft = {
  javascript = { "prettier" },
  typescript = { "prettier" },
  html = { "prettier" },
  css = { "prettier" },
  svelte = { "prettier" },
  json = { "prettier" },
}

Auto-Format Behavior

Files are automatically formatted on save using a BufWritePre autocommand:
vim.api.nvim_create_autocmd("BufWritePre", {
  callback = function(args)
    require("conform").format({ bufnr = args.buf })
  end,
})
Only configured file types will be auto-formatted. If you want to add support for additional languages, update the formatters_by_ft table in lua/magictt/plugins/conform.lua.

Adding New Language Servers

To add support for a new language:
1

Find the LSP server name

Visit nvim-lspconfig server configurations to find the server name for your language.
2

Add to ensure_installed

Edit lua/magictt/plugins/lsp/mason.lua and add the server name to the ensure_installed list:
ensure_installed = {
  -- ... existing servers ...
  "rust_analyzer",  -- Add Rust support
}
3

Restart Neovim

Restart Neovim and Mason will automatically install the new language server.
4

(Optional) Add formatter

If you want auto-formatting, add a formatter to conform.lua:
formatters_by_ft = {
  rust = { "rustfmt" },
}
And add the formatter to mason-tool-installer in mason.lua:
ensure_installed = {
  "rustfmt",
}

Troubleshooting

LSP Not Working

Run :LspInfo in Neovim to see which language servers are attached to the current buffer.
Use <leader>rs to restart the LSP server for the current buffer.
Open Mason with <leader>mm and verify the language server is installed (✓ icon).
Check :messages or :LspLog for error messages.

Formatter Not Working

  1. Verify the formatter is installed in Mason (<leader>mm)
  2. Check that your file type is configured in formatters_by_ft
  3. Ensure the formatter supports your file type

Vim Options

Core Vim settings including diagnostic display

Keymaps

All LSP keybindings and shortcuts

Build docs developers (and LLMs) love