Вернуться назад

nvim4

lsp

Для начала установим typescript и typescript-language-server:

sudo npm install --global typescript typescript-language-server

Запустить typescript-language-server:

typescript-language-server --stdio

Вот пример файла с настройкой и запуском LSP-сервера:

-- ~/.config/nvim/lua/lsp.lua

-- 1. Описание сервера
vim.lsp.config['tsserver'] = {
  cmd = { 'typescript-language-server', '--stdio' },
  filetypes = { 'javascript', 'javascriptreact', 'typescript', 'typescriptreact' },
  root_markers = { 'package.json', 'tsconfig.json', 'jsconfig.json', '.git' },
  settings = {}, -- настройки tsserver можно оставить пустыми
}

-- 2. Включение сервера
vim.lsp.enable('tsserver')

И давайте подключим этот LSP-сервер в самом низу файла init.lua:

-- ~/.config/nvim/init.lua

-- ...

require("lsp")

Проверить, работает ли LSP-сервер:

:checkhealth vim.lsp

Ещё один способ проверить, работает ли LSP-сервер:

:lua print(vim.inspect(vim.lsp.get_clients({bufnr=0})))

-- Если вывод: "{}", то значит LSP-сервер не работает
-- А если вывод есть, то всё в порядке.

-- Если запустить эту команду в .js- / .ts-файле, то получим вывод,
-- а если запустить, например, в .lua-файле, то получим: "{}".
-- Значит, для .lua LSP-сервер не работает.

Если открыть .js-файл, то мы можем заметить напротив некоторых строк пометки (если включен signcolumn - vim.opt.signcolumn = "yes"):

Как посмотреть подсказку / комментарий. Нужно переместиться на строку с подсказкой / ошибкой и нажать "K".

nvim-cmp

Также для работы понадобятся:

Сам nvim-cmp ничего не предлагает. nvim-cmp – это менеджер меню, а варианты ему приносят источники (sources). Каждая строка в dependencies – один источник данных. cmp-nvim-lsp – самый важный источник. Это мост между LSP и nvim-cmp. LSP не участвует в автодополнении без cmp-nvim-lsp.

-- ~/.config/nvim/lua/plugins/cmp.lua

return {
  {
    'hrsh7th/nvim-cmp',
    dependencies = {
      'hrsh7th/cmp-nvim-lsp',
      'hrsh7th/cmp-buffer',
      'hrsh7th/cmp-path',
    },
    config = function()
      local cmp = require('cmp')

      cmp.setup({
        completion = {
          completeopt = 'menu,menuone,noselect',
        },

        mapping = cmp.mapping.preset.insert({
          ['<C-Space>'] = cmp.mapping.complete(),
          ['<CR>'] = cmp.mapping.confirm({ select = true }),
          ['<Tab>'] = cmp.mapping.select_next_item(),
          ['<S-Tab>'] = cmp.mapping.select_prev_item(),
        }),

        sources = {
          { name = 'nvim_lsp' },
          { name = 'buffer' },
          { name = 'path' },
        },
      })
    end,
  },
}

cmp.mapping – это не vim.keymap. Это внутренняя система обработки клавиш плагина nvim-cmp. Она работает только когда активно completion-меню. Это логика UI-автодополнения, а не редактора.

А затем подключаем nvim-cmp в init.lua:

-- ~/.config/nvim/init.lua

-- ...
require("lazy").setup({
   spec = {
      { ... },
      { import = "plugins.cmp" },
   },
   install = { colorscheme = { "habamax" } }
})

Теперь можно открыть .js- или .ts-файл и автодополнение должно работать.

Сниппеты

Подправим файл ~/.config/nvim/lua/plugins/cmp.lua:

-- ~/.config/nvim/lua/plugins/cmp.lua

return {
{
  'hrsh7th/nvim-cmp',
  dependencies = {
    -- completion
    'hrsh7th/cmp-nvim-lsp',
    'hrsh7th/cmp-buffer',
    'hrsh7th/cmp-path',

    -- snippets
    'L3MON4D3/LuaSnip',
    'saadparwaiz1/cmp_luasnip',
    'rafamadriz/friendly-snippets',
  },
  config = function()
    local cmp = require('cmp')
    local luasnip = require('luasnip')

    -- Загружаем сниппеты из friendly-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-Space>'] = cmp.mapping.complete(),
	['<CR>'] = cmp.mapping.confirm({ select = true }),

	['<Tab>'] = cmp.mapping(function(fallback)
	  if cmp.visible() then
	    cmp.select_next_item()
	  elseif luasnip.expand_or_jumpable() then
	    luasnip.expand_or_jump()
	  else
	    fallback()
	  end
	end, { 'i', 's' }),

	['<S-Tab>'] = cmp.mapping(function(fallback)
	  if cmp.visible() then
	    cmp.select_prev_item()
	  elseif luasnip.jumpable(-1) then
	    luasnip.jump(-1)
	  else
	    fallback()
	  end
	end, { 'i', 's' }),
      }),

      sources = {
	{ name = 'nvim_lsp' },
	{ name = 'luasnip' },  -- добавим ещё и luasnip
	{ name = 'buffer' },
	{ name = 'path' },
      },
    })
  end,
},
}

Теперь, когда мы запустим .js- или .ts-файл и начнём набирать код – например, for, – то в выпадающем списке появится выбор сниппета: for~ snippet.

lua-languager-server

Для начала установим lua-languager-server:

sudo pacman -S lua-language-server

# Проверяем:
lua-language-server --version

Добавляем LSP-сервер для Lua в ~/.config/nvim/lua/lsp.lua:

-- ~/.config/nvim/lua/lsp.lua

-- 1. Описание TypeScript- / JavaScript-сервера:
vim.lsp.config['tsserver'] = {
  cmd = { 'typescript-language-server', '--stdio' },
  filetypes = { 'javascript', 'javascriptreact', 'typescript', 'typescriptreact' },
  root_markers = { 'package.json', 'tsconfig.json', 'jsconfig.json', '.git' },
  settings = {}, -- настройки tsserver можно оставить пустыми
}

-- 2. Описание Lua-сервера:
vim.lsp.config['lua_ls'] = {
  cmd = { 'lua-language-server' },
  filetypes = { 'lua' },
  root_markers = { '.git', '.luarc.json', '.luarc.jsonc' },
  settings = {
    Lua = {
      runtime = {
        version = 'LuaJIT', -- важно для Neovim
      },
      diagnostics = {
        globals = { 'vim' }, -- чтобы не ругался на vim.*
      },
      workspace = {
        library = vim.api.nvim_get_runtime_file('', true),
        checkThirdParty = false,
      },
    },
  },
}

-- 3. Включение серверов:
vim.lsp.enable('tsserver')
vim.lsp.enable('lua_ls')

Теперь nvim-cmp и сниппеты должны понимать и Lua.


    lala