LINUX.ORG.RU

Настройка Neovim/Nvim

 , , ,


5

4

Введение

Neovim или просто Nvim — это современный редактор, возникший как замена Vim.

Vim — это текстовый редактор для терминала, уникальный прежде всего наличием различных режимов работы (нормальный, редактирования, выделения, замены, командный), которые позволяют выполнять абсолютно все действия с клавиатуры без использования мыши, что заметно увеличивает скорость работы с текстом. Так же он является программируемым, что, наверное, и является его самым большим плюсом.

Да, вы можете взять VS Code, поставить кучу плагинов чтобы получить необходимый функционал, но сам редактор, плагины настраиваются через JSON, что не позволяет добавить какую-нибудь пользовательскую функцию для сортировки файлов в проводнике или навесить сочетание на вызов функции… Там такое можно сделать через написание расширений, что намного сложнее и трудозатратнее чем в том же виме + в последнем меньше ограничений со стороны APIVS Code нельзя радикально переделать интерфейс, заменить проводник на другой и т.п.).

Vim возник более 30 с лишним лет назад. Поэтому, в нём нет многих привычных вещей, например, нативной поддержки LSP, которые просто не существовали в момент его создания. Вместо этого vim имеет встроенную поддержку утилиты ctags, которая была чем-то прорывным в 1991-м, но сейчас ею почти никто не пользуется. Vim нельзя назвать мёртвым: он активно развивается, обрастая функционалом. Но то, что в нем для настраивания используется свой собственный язык Vimscript, тормозит его внедрение.

LSP — это протокол, используемый текстовыми редакторами для автодополнения, получения справки и т. д., ставший стандартом в отрасли. Он был придуман Microsoft и так понравился всем, что сейчас почти нет современных редакторов, которые бы его не поддерживали. LSP представляет собой сетевой клиент-серверный протокол, работающий через JSON-RPC. Это значит, что данные могут запрашиваться и получаться по сети (в основном по локальной, но никто не запрещает через Интернет). Нет принципиальной невозможности реализовать клиент на Vimscript, но скорость работы последнего будет оставлять желать лучшего, так как Vimscript не является сетевым языком как и языком общего назначения, поэтому в нём нет поддержки тредов (он однопоточный) и асинхронности, которые бы ускоряли автодополнение. Не говоря уже о том, что Vimscript просто тормоз.

Замена Vimscript на Lua в Neovim решала эти проблемы. Lua является стандартным встраиваемым языком для скриптинга в играх или для настроек в программах. Сам язык напоминает что-то среднее между JS без классов и чем-то похожим на Pascal наличием оператора end. Lua не просто быстрый, он очень быстрый, так как поддерживает JIT-компиляцию.

Nvim имеет обратную совместимость с Vim, он поддерживает как задание настроек через vim-файлы, так и почти все его настройки за небольшим исключением. Это означает, что большинство плагинов для Vim будут работать в Nvim.

Установка Neovim в моём дистрибутиве выглядит так:

sudo pacman -S nvim

Во всех популярных дистрибутивах Nvim можно поставить стандартным пакетным менеджером.

Настройки

Главный файл настроек в Nvim располагается в ~/.config/nvim. Он должен называться init.vim или init.lua.

Но для задания конфигов мы будем использовать именно Lua, так как последний поддерживает полноценные модули.

У нас будет такая структура:

~/.config/nvim
├── init.lua
└── lua
    ├── configs
    │   ├── autocmds.lua
    │   ├── keymaps.lua
    │   ├── options.lua
    │   └── plugins.lua
    └── utils.lua

В директории с конфигом находится директория lua. Такое название является обязательным. Файлы в ней можно подключать через require. В lua для подключаемых конфигов я создал configs.

Следует отметить, что использование неймспейсов является хорошей практикой, так как позволяет избежать конфликта имен. Например, можно ложить все в lua/user. lua/configs так же нормальный вариант, так как встроенного модуля configs как и utils не существует, а вот lua/foo.lua будет конфликтовать с плагином foo.

В качестве пакетного менеджера в Nvim часто используют старый, добрый vim-plug, так как он позволяет использовать vimrc вместо написания нового конфига. Для наших же целей он не подходит. Мы будем использовать lazy.nvim, который на данный момент является лучшим пакетным менеджером.


lazy.nvim по умолчанию грузит модули асинхронно. Вот небольшая справка по его использованию:

-- Основной вызов Lazy.nvim
require("lazy").setup(opts)

-- Где opts — это таблица (массив) с описаниями плагинов.
-- Каждый элемент таблицы описывает один плагин.

{
  -- Указывается репозиторий плагина на GitHub
  "github_user/repo",

  -- Необязательное поле: зависимости (будут установлены автоматически)
  dependencies = {
    "github_user/dependency1",
    "github_user/dependency2",
    -- и т.д.
  },

  -- Настройка плагина: вызывается при его загрузке
  -- Можно использовать для ручной инициализации, настройки событий и т.д.
  config = function()
    local plugin = require("plugin_name")
    plugin.setup({
      option1 = true,
      option2 = "value",
    })
  end,

  -- Альтернатива config: если плагин поддерживает setup(opts),
  -- можно указать опции напрямую, и lazy.nvim сам вызовет setup(opts)
  opts = {
    option1 = true,
    option2 = "value",
  },

  -- Если устраивают настройки по умолчанию
  -- (и setup вызывается без параметров), можно передать пустую таблицу
  opts = {},

  -- Или можно просто указать config = true, если плагин сам настроится при require
  config = true,

  -- Указывает, загружать ли плагин по требованию (true по умолчанию).
  -- Устанавливаем lazy = false, если плагин должен быть загружен сразу (например, тема или ключи)
  lazy = false,

  -- Определение горячих клавиш
  keys = {
    { "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Поиск файлов" },
    { "<C-s>", ":w<CR>", desc = "Сохранить файл", mode = "n" },
    -- mode по умолчанию = "n", можно задать "i", "v", "n", "t" и т.п.
  },

  -- Можно указать команду или событие, при котором плагин будет загружен:
  cmd = { "SomeCommand" },
  event = { "BufReadPost", "BufNewFile" },
}

-- Альтернатива: можно передать путь к модулю, экспортирующему список плагинов
require("lazy").setup("path.to.plugins")

-- Где path/to/plugins.lua может выглядеть как:
return {
  {
    "github_user/foo",
    opts = {},
  },
  {
    "github_user/bar",
    config = function()
      require("bar").setup()
    end,
  },
}

-- Или если в каталоге `lua/path/to/plugins/` несколько файлов:
-- каждый файл экспортирует таблицу(ы) с описанием плагинов:
-- plugins/foo.lua:
return {
  "github_user/foo",
  opts = {},
}

-- plugins/bar.lua:
return {
  "github_user/bar",
  config = true,
}

-- Ошибка: модуль не найден
local foo = require("foo")
require("lazy").setup({ ... })

-- Так же приведет к ошибке, так как модуль ленивый
require("lazy").setup({
  {
    "github_user/foo",
    lazy = true, -- это значение по умолчанию
  },
})

local foo = require("foo")

-- Таким образом, самый надежный вариант
{
  "github_user/foo",
  dependencies = { "github_user/bar" },  -- зависимости тоже гарантированно доступны для загрузки
  config = function()
    local foo = require("foo")
    foo.setup {}
    local bar = require("bar")
    bar.setup()
  end,
}

В init.lua у нас содержится код для автоматической установки lazy.nvim, а также подключение различных модулей с настройками:

-- disable netrw at the very start of your init.lua
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1

-- Установка lazy.nvim
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",
    lazypath
  })
end
vim.opt.rtp:prepend(lazypath)

-- Клавиша leader должна быть задана до загрузки плагинов
vim.g.mapleader = ' '

-- Настройка плагинов
require("lazy").setup("configs.plugins")

-- Настройки задаем после загрузки плагинов
require("configs.options")
require("configs.keymaps")
require("configs.autocmds")

options.lua — это общие настройки, которые я позаимствовал из своего старого конфига Vim за небольшими отличиями. Например, в Nvim set hidden — это поведение по умолчанию, а paste вообще выбросили.

lua/configs/options.lua

local config_dir = vim.fn.stdpath('config')
local opt = vim.opt

-- Настройки интерфейса
opt.termguicolors = true
opt.lazyredraw = true
opt.background = "dark"
opt.guifont = "JetBrainsMono Nerd Font:h12"
opt.guicursor = "n-v-c:block,i-ci-ve:ver25,r-cr:hor20,o:hor20"

-- Нумерация строк
opt.number = true
--opt.relativenumber = true

-- Подсветка текущей строки
opt.cursorline = true

-- Прокрутка
opt.scrolloff = 5     -- по вертикали
opt.sidescrolloff = 5 -- по горизонтали

-- Отображение различных элементов
opt.signcolumn = "yes"
opt.showcmd = false
opt.laststatus = 3
opt.showmode = false -- не показывать режим (--INSERT и тп) в самом низу

-- Перенос строк
opt.wrap = true
opt.linebreak = true

-- Отображение различных символов
opt.list = true
opt.listchars = {
  tab = '→ ',
  trail = '·',
  nbsp = '␣',
  extends = '❯',
  precedes = '❮'
}
opt.fillchars = { eob = " " } -- вместо ~ отображаем просто пустые строки

-- Отступы и табуляция
opt.expandtab = true -- заменять символы табуляции на пробелы при отрисовке
opt.tabstop = 4      -- на сколько пробелов заменяется символ табуляции при отображении
opt.shiftwidth = 2   -- количество пробелов, вставляемых при шифтинге
opt.softtabstop = 2  -- ширина отступа
-- автоматически определять количество пробелов для отступа
opt.autoindent = true
opt.smartindent = true
opt.breakindent = true -- при переносе строки добавлять отступы

-- Поиск
opt.ignorecase = true
opt.smartcase = true
opt.incsearch = true
opt.hlsearch = true
opt.wrapscan = true
opt.inccommand = "split"

-- Файлы и буферы
-- В последнем nvim вроде всегда такое поведение
-- opt.hidden = true
-- Используем системный буфер для копирования текста
-- Требует наличия xclip или wl-copy!
opt.clipboard = "unnamedplus"
-- Бекапы, файлы подкачки, undo- и shada-файлы хранятся в ~/.local/state/nvim
-- Отключаем создание бекапов и файлов подкачки
opt.swapfile = false
opt.backup = false
opt.writebackup = false
opt.autoread = true -- Обновлять буфер при изменении файла извне
-- Делаем возможной отмену изменений уже после закрытия файла
opt.undofile = true
opt.undolevels = 1000
opt.shada = "!,'1000,<50,s10,h" -- ограничения для shada-файлов (от share data)
opt.confirm = true

-- Разделение окон
opt.splitbelow = true
opt.splitright = true

-- Мышь и работа с текстом
opt.mouse = "a"
opt.mousemoveevent = true
-- Выделение текста стрелками с зажатым Shift
opt.keymodel = "startsel,stopsel"
-- При переключении системной раскладки перестают работать привязки клавиш.
-- В vim можно включить встроенную русскую раскладку с переключением по Ctrl-6
opt.keymap = "russian-jcukenwin"
-- Делаем раскладкой по умолчанию английскую
opt.iminsert = 0
opt.imsearch = 0
-- Привычное перемещение курсора
opt.whichwrap:append("hl<>[]")

-- Автодополнение
opt.wildmenu = true
opt.wildmode = "longest:full,full"
-- Можно исключить из дополнения определенные типы файлов, имеющие бинарный формат
opt.wildignore:append { '*.o', '*.obj', '*.py[co]', '__pycache__/*', '*.so', '*.zip', '*.rar', '*.tar.*', '*.gz', '*.docx', '*.xlsx', '*.pdf', '*.jpg', '*.jpeg', '*.gif', '*.png' }
opt.completeopt = "menuone,noselect,noinsert"
opt.pumheight = 10 -- высота всплывающего меню с вариантами для дополнения

-- Таймауйты
opt.timeoutlen = 500
opt.updatetime = 250

-- spell
opt.spell = false
opt.spelllang = { "ru", "en" }

local spell_dir = config_dir .. '/spell'
if vim.fn.isdirectory(spell_dir) == 0 then
  vim.fn.mkdir(spell_dir, 'p')
end

Тут хранятся пользовательские сочетания клавиш, некоторые из них задаются странным образом — внутри функции:

lua/configs/keymaps.lua

local map = require("utils").map

map('n', '<C-a>', 'ggVG', "Select all text")
map('i', '<C-a>', '<Esc>ggVG', "Select all text")

map('n', '<C-q>', '<cmd>q<CR>', "Close current window")
map('n', '<C-x>', '<cmd>bd<CR>', "Delete current buffer")
-- В Neovim это сочетание уже используется
-- map('', '<C-s>', '<cmd>w<CR>', "Save file")
map('n', '<leader>w', '<cmd>w<CR>', "Save file")

-- Отступы привычнее добавлять с помощью Tab
map('n', '<Tab>', '>>_', "Increase indent")
map('n', '<S-Tab>', '<<_', "Decrease indent")
map('i', '<S-Tab>', '<C-D>', "Decrease indent")
map('v', '<Tab>', '>gv', "Increase indent")
map('v', '<S-Tab>', '<gv', "Decrease indent")

map('n', '<Esc>', '<cmd>nohlsearch<CR><Esc>', "Clear search highlight")

map('n', '<C-Up>', '<cmd>bp<CR>', "Previous buffer")
map('n', '<C-Down>', '<cmd>bn<CR>', "Next buffer")

map('n', '<C-h>', '<C-w>h', "Focus left window")
map('n', '<C-j>', '<C-w>j', "Focus lower window")
map('n', '<C-k>', '<C-w>k', "Focus upper window")
map('n', '<C-l>', '<C-w>l', "Focus right window")

map('n', '<A-h>', '<C-w>H', "Move window left")
map('n', '<A-j>', '<C-w>J', "Move window down")
map('n', '<A-k>', '<C-w>K', "Move window up")
map('n', '<A-l>', '<C-w>L', "Move window right")

map('n', '<A-Left>', '<cmd>vertical resize -2<CR>', "Decrease width")
map('n', '<A-Right>', '<cmd>vertical resize +2<CR>', "Increase width")
map('n', '<A-Down>', '<cmd>resize -2<CR>', "Decrease height")
map('n', '<A-Up>', '<cmd>resize +2<CR>', "Increase height")

map('v', "J", ":m '>+1<CR>gv=gv", "Shift visual selected line down")
map('v', "K", ":m '<-2<CR>gv=gv", "Shift visual selected line up")

map('n', '<leader>h', '<cmd>split<CR>', "Horizontal split")
map('n', '<leader>v', '<cmd>vsplit<CR>', "Vertical split")

-- nvim автоматически добавляет переменную $MYVIMRC, ее не нужно добавлять
map('n', '<leader>ev', '<cmd>edit $MYVIMRC<CR>', "Edit vim config")
map('n', '<leader>sv', '<cmd>so $MYVIMRC<CR>', "Reload vim config")

-- F3-F11 лучше оставить для дебаггера
map('', '<F2>', ":setlocal spell!<cr>", "Toggle spell check")

map("n", "<leader>ff", "<cmd>Telescope find_files<cr>", "find file")
map("n", "<leader>fg", "<cmd>Telescope live_grep<cr>", "Find [using] grep")
map("n", "<leader>fb", "<cmd>Telescope buffers<cr>", "find buffer")

-- Можно использовать любое из сочетаний с Ctrl+T/N/P, так как на них навешен бесполезный функционал
map("n", "<C-t>", "<cmd>NvimTreeToggle<CR>", "Toggle nvim tree")

-- Можно через telescope тоже самое делать
local setup_lsp_keymaps = function(_, bufnr)
  map("n", "gd", vim.lsp.buf.definition, "Go to definition", bufnr)
  map("n", "gD", vim.lsp.buf.declaration, "Go to declaration", bufnr)
  map("n", "gi", vim.lsp.buf.implementation, "Go to implementation", bufnr)
  map("n", "gr", vim.lsp.buf.references, "List references", bufnr)
  map("n", "K", vim.lsp.buf.hover, "Hover documentation", bufnr)
  -- На эту клавишу в режиме редактирования по умолчанию уже задано это действие
  map("n", "<C-s>", vim.lsp.buf.signature_help, "Signature help", bufnr)
  map("n", "<leader>rn", vim.lsp.buf.rename, "Rename symbol", bufnr)
  map("n", "<leader>ca", vim.lsp.buf.code_action, "Code action", bufnr)
  map("n", "]d", vim.diagnostic.goto_next, "Next diagnostic", bufnr)
  map("n", "[d", vim.diagnostic.goto_prev, "Previous diagnostic", bufnr)
  map("n", "<leader>e", vim.diagnostic.open_float, "Show diagnostics", bufnr)
end

return {
  setup_lsp_keymaps = setup_lsp_keymaps
}

В lua/utils.lua я вынес вспомогательную функцию для задания сочетаний, она выше импортируется:

local M = {}

-- Универсальная функция для биндингов
function M.map(mode, keys, command, desc, bufnr)
  local opts = { desc = desc, silent = true }
  if bufnr then
    opts.buffer = bufnr
  end
  vim.keymap.set(mode, keys, command, opts)
end

return M

В Nvim LSP встроенный. Например, Ctrl-S по умолчанию в режиме редактирования вызывает справку. Так же нам не нужны никакие плагины для комментариев — для этого есть сочетание gc.


lua/configs/plugins.lua

local setup_lsp_keymaps = require("configs.keymaps").setup_lsp_keymaps

return {
  -- Файловый менеджер
  {
    "nvim-tree/nvim-tree.lua",
    dependencies = { "nvim-tree/nvim-web-devicons" },
    config = function()
      require("nvim-tree").setup({
        view = { width = 30 },
        filters = { dotfiles = false },
        git = { enable = true },
        actions = {
          open_file = {
            quit_on_open = true, -- закроет дерево после открытия файла
          },
        },
        -- авто-закрытие при последнем буфере
        -- только если включена эта настройка:
        hijack_netrw = true,
      })
    end,
  },

  -- Поиск по файлам
  {
    "nvim-telescope/telescope.nvim",
    dependencies = { "nvim-lua/plenary.nvim" },
    config = function()
      require('telescope').setup({
        -- Тут какие-то настройки
      })
      -- require('telescope').load_extension('fzf')
    end
  },

  -- tree-sitter используется для парсинга сходников
  -- :checkhealth nvim-treesitter
  {
    "nvim-treesitter/nvim-treesitter",
    build = ":TSUpdate",
    config = function()
      local configs = require("nvim-treesitter.configs")

      configs.setup({
        -- Парсеры для каждого языка нужно ставить отдельно
        ensure_installed = { "c", "lua", "vim", "vimdoc", "python", "go", "rust", "java", "javascript", "php", "vue", "html", "json", "toml", "yaml" },
        sync_install = false,
        auto_install = true,
        highlight = { enable = true },
        indent = { enable = true },
      })
    end
  },

  -- LSP и Автодополнение
  -- https://medium.com/@rishavinmngo/how-to-setup-lsp-in-neovim-1c3e5073bbd1
  {
    "hrsh7th/nvim-cmp",
    dependencies = {
      'neovim/nvim-lspconfig',
      'hrsh7th/cmp-nvim-lsp',
      'hrsh7th/cmp-buffer',
      'hrsh7th/cmp-path',
      'hrsh7th/cmp-cmdline'
    },
    config = function()
      local cmp = require('cmp')
      cmp.setup({
        sources = {
          { name = 'nvim_lsp' },
          { name = 'buffer' },
        },
        mapping = cmp.mapping.preset.insert({
          ['<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 = true }),
        })
      })

      local lspconfig = require('lspconfig')
      local capabilities = require("cmp_nvim_lsp").default_capabilities()

      -- npm install -g pyright
      -- sudo pacman -S gopls lua-language-server
      -- Mason может автоматически ставить зависимости
      -- Тут нужно вписать названия серверов, поддерживаемых nvim-lspconfig
      local servers = {
        'pyright',
        'gopls',
        'lua_ls',
      }

      for _, lsp in ipairs(servers) do
        lspconfig[lsp].setup {
          on_attach = setup_lsp_keymaps,
          capabilities = capabilities,
        }
      end
    end
  },

  -- Выделение отступов
  {
    "lukas-reineke/indent-blankline.nvim",
    config = function()
      require("ibl").setup()
    end
  },

  -- Нижняя строка статуса
  {
    "nvim-lualine/lualine.nvim",
    dependencies = 'nvim-tree/nvim-web-devicons',
    config = function()
      require('lualine').setup({
        sections = {
          lualine_x = {
            -- Добавим отображение раскладки
            {
              function()
                if vim.opt.iminsert:get() > 0 and vim.b.keymap_name then
                  return '⌨ ' .. vim.b.keymap_name
                end
                return ''
              end,
              cond = function() -- Показывать только если раскладка активна
                return vim.opt.iminsert:get() > 0 and vim.b.keymap_name ~= nil
              end,
            },
            'encoding',
            'fileformat',
            'filetype',
          }
        }
      })
    end
  },

  -- Верхняя строка статуса (заменяет табы)
  {
    'akinsho/bufferline.nvim',
    version = "*",
    dependencies = 'nvim-tree/nvim-web-devicons',
    config = function()
      require("bufferline").setup {
        options = {
          mode = "buffers",
          separator_style = "slant"
        }
      }
    end,
  },

  -- Тема
  {
    "folke/tokyonight.nvim",
    lazy = false,
    priority = 1000,
    opts = {},
    config = function(_, opts)
      require("tokyonight").setup(opts)
      vim.cmd [[colorscheme tokyonight-storm]]
    end
  },

  -- Фиксим прозрачность
  {
    "xiyaowong/transparent.nvim",
    config = function()
      require('transparent').setup({
        extra_groups = {
          'NormalFloat', -- plugins which have float panel such as Lazy, Mason, LspInfo
        },
        exclude_groups = { 'CursorLine' },
      })
    end
  }
}

В plugins.lua перечислены плагины. Обратите внимание, что внутри почти каждого блока объявлена функция config. Она вызывается после установки и/или после готовности плагина к использованию, после чего в большинстве случаев нужно импортировать плагин и вызвать функцию setup, объявленную внутри, в которую передаётся ассоциативный массив с настройками.

В Neovim парсинг файлов с исходниками происходит через плагины для Tree-sitter (является зависимостью редактора). С помощью него строится синтаксическое дерево, которое используется для автодополнения, анализа кода, а также опционально для подсветки синтаксиса. Пакет с одноимённым названием, который мы устанавливаем, лишь содержит список парсеров, доступных для скачивания и установки, а также может их скачивать.

nvim-lspconfig содержит названия LSP-серверов и их стандартные настройки, которые можно переопределить. Языковые сервера можно устанавливать автоматически с помощью Mason. Их установка с помощью последнего позволяет изолировать окружение для разработки. Однако, если у вас все эти средства уже установлены, например, так как вами используется VSCode, то Mason будет лишним.

Помимо плагина для комментариев, не нужен и плагин для editorconfig, так как последний поддерживается из коробки.


В lua/configs/autocmds.lua находятся команды, которые активируются при определённых событиях:

-- Автоперечтение файла при изменении
vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold" }, {
  command = "checktime",
})

-- Форматирование при сохранении
vim.api.nvim_create_autocmd("BufWritePre", {
  callback = function()
    vim.lsp.buf.format {
      async = false
    }
  end,
})

-- Показывать всплывающие окна с ошибками при наведении курсора
vim.api.nvim_create_autocmd("CursorHold", {
  callback = function()
    vim.diagnostic.open_float(nil, { focusable = false })
  end,
})

Заключение

Получившийся конфиг полностью готов к использованию. Вы можете ознакомиться с ним, посетив мой репозиторий на Github.

А так же себе его развернуть:

git clone https://github.com/s3rgeym/nvim-config ~/.config/nvim 

Nvim, хотя и является редактором для терминала, но так же для него существуют т. н. фронтенды. Из популярных — Neovim-qt и Neovide. Последний имеет поддержку лигатур, GPU-ускорение и анимации для прокрутки текста и курсора.

Альтернативой Nvim являются Kakoune и Helix. Если первый представляет собой скорее Vim здорового человека (или криворука, который не в состоянии настроить первый — решайте сами), то Helix можно рассматривать как преднастроенный Nvim, где вместо ковыряния Lua-лапши можно редактировать TOML. Для кого-то это будет огромным плюсом, но, как по мне, это накладывает гигантские ограничения и противоречит самой концепции программируемого редактора. Хотя я их и не советую использовать, но об их существовании стоит упомянуть, так как они скорее служат для того, чтобы понять, подходит ли для тебя Vim/Nvim.

★★★

Проверено: hobbit ()
Последнее исправление: dataman (всего исправлений: 12)

LSP представляет собой сетевой клиент-серверный протокол. Это значит, что данные гоняются туда-сюда по сети

Нет, man JSON-RPC.

dataman ★★★★★
()

Угадал автора, не дочитав даже до середины содержимого статьи. Очень, очень слабо (это мнение как пользователя nvim, мнение как модератора: годится в качестве статьи).

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 2)

Helix — это преднастроенный Nvim

Ага, написанный на Rust. То есть, вообще не имеет никакого отношения к *vim.

dataman ★★★★★
()
Ответ на: комментарий от dataman

а какая логика? ну типа fish на rust переписали, теперь он не имеет отношения к шеллам? ржавый мне не нравится, но это обычный язык

rtxtxtrx ★★★
() автор топика
Ответ на: комментарий от SurpriseCat

а чем надо пользоваться, маэстро? бегая за мной и спамя клоунами, ты должен какую-то потаенную истину знать которой делиться не спешишь

rtxtxtrx ★★★
() автор топика
Ответ на: комментарий от SurpriseCat

В наше время формат простого текста ничуть не менее востребован, чем в какое-то другое время — он самы простой и самый удобный для множества различных применений, от конфигов до небольших заметок.

Ну а Vim/NeoVim — это просто по сути один из очень немногих полноценных текстовых редакторов (то есть, программ для работы с этим форматом), если не единственный действительно удобный и эффективный. Сколько других пробовал — везде чего-то да не хватает по сравнению с vim.

Конкретно NeoVim или оригинальный Vim — уже совсем субъективщина, если честно. Когда я перешёл на NeoVim, у него были киллерфичи, затем в Vim многое из этого реализовали тоже, но смысла возвращаться обратно я тоже особо не вижу — возможно и сравняли, но не превзошли.

CrX ★★★★★
()
Ответ на: комментарий от rtxtxtrx

а какая логика?

Простая, «преднастроенный Nvim» – он сам, с конфигами.
А Helix даже не форк, а написан на другом языке.

dataman ★★★★★
()
Ответ на: комментарий от rtxtxtrx

Феррари – преднастроенная Жигули, если так понятнее.

dataman ★★★★★
()

Vim нельзя назвать мёртвым: он активно развивается, обрастая функционалом. Но то, что в нем для настраивания используется свой собственный язык Vimscript, тормозит его внедрение

тормозит его внедрение

Мда.

habamax ★★★
()

В Neovim парсинг файлов с исходниками происходит через Tree-sitter. С помощью него строится синтаксическое дерево, которое используется для автодополнения, анализа кода, а также для подсветки синтаксиса. Пакет с одноимённым названием, который мы устанавливаем, лишь содержит список парсеров, доступных для скачивания и установки, а также может их скачивать.

То есть можно удалить все syntax/*.vim файлы из неовима?

Люди не знакомые с неовимом могут неверно понять, что там все только на триситтере.

habamax ★★★
()
Ответ на: удаленный комментарий

Молодец. Пирожок взял уже?

Zhbert ★★★★★
()

Ну сколько раз уже просили не ставить тег vim в темы про neovim!

shell-script ★★★★★
()

Статью не читал, но на скрине какая-то новогодняя ёлка. Все эти разноцветные панели точно нужны? Постановляю: мультиплексер выкинуть, из вима мишуру убрать: set ruler laststatus=0. Ах да невим не нужен.

bread
()
Ответ на: комментарий от qulinxao3

Когда шлёпаешь текут вверх. Окуни. Но если бы не, то даже порох. Жаль, что инсинуации на дребезг.

Zhbert ★★★★★
()

Nvim, хотя и является редактором для терминала, но так же для него существуют т. н. фронтенды. Из популярных — Neovim-qt и Neovide.

А кто реально пользуется - посоветуйте. Только из личного опыта, пожалуйста: гуглить и пробовать я сам могу.

Нужно на Винде, поэтому терминал не вариант, только GUI.

На прошлом компе использовал Gvim. Настроил под себя, скачал приличную тему для иконок таскбара - всё устраивало.

Сейчас новый комп (Виндовый комп меняется со сменой работы, потому как дома только Линукс). Notepad++ уже не хватает. Думаю опять поставить vim+GUI, заодно Neovim попробовать.

Какой годный фронтенд для Neovim?

Kroz ★★★★★
()
Ответ на: комментарий от SurpriseCat

Ну чтоб на роутерах всяких vi не использовать, если разработчики прошивки vim туда закинули.

peregrine ★★★★★
()
Ответ на: комментарий от Kroz

Нужно на Винде, поэтому терминал не вариант

Там что икспи у тебя? Потому как повершел вполне юзабелен.

PS

Я правда из повершела запускал vim на удалённых серверах, но он и локально умеет. Как по мне вполне нормально, чтоб файлы редактировать.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от CrX

Мне в vim сильно не хватает всего одной вещи, из-за которой пришлось частично мигрировать на neovim — поддержки буфера обмена на wayland. Всякие костыли типа ремапов сочетаний на wclip нормально не работают, и тот же PRIMARY буфер в таком варианте не работает нормально даже с костылями.

Werenter ★★★
()
Ответ на: комментарий от peregrine

Потому как повершел вполне юзабелен.

Look and fill не тот. У меня в Линуксе правильные шрифты, цветовая схема, хоткеи (в первую очередь в tmux). В PowerShell это недостижимо.

Kroz ★★★★★
()

У нас будет такая структура

А я все в один файл свалил. Потому что когда установка и подключение плагина в одном файле, его параметры в другом, а кейбиндинги в третьем это как-то не очень удобно оказалось. Да и искать что к чему и редактировать в случае одного файла проще.

micronekodesu ★★★
()
Ответ на: комментарий от micronekodesu

не проще. посмотри мой конфиг на гитхабе. там с десяток файлов. все двояко. лучше все сочетания в одном месте держать, но не всегда так можно сделать… это просто практика из мира программирования: функции не более 20-30 строк, все разносить по логическим модулям, не допускать мега-файлов по десятки тысяч строк…

rtxtxtrx ★★★
() автор топика

А что там за позиция «Vim я не пользуюсь больше и другим не советую из-за политической позиции его разработчиков.» ?

LunarStar
()

…то Helix можно рассматривать как преднастроенный Nvim, где вместо ковыряния Lua-лапши можно редактировать TOML.

Есть еще одно существенное различие в подходе к командам нормального режима.

У вима они выглядят как действие->область/перемещение, после чего они мгновенно применяются. Типа dw - удалить до начала следующего слова.

В хеликсе подход область/перемещение(с выделением)->действие. Например, w - перемещает к началу следующего слова и выделяет область, затем d - удалит выделение.

Из-за чего в хеликсе порой приходится нажать на кнопку больше, но его легче освоить, так как ты видишь область применения действия перед его применением. Плюс типичные команды связанные с областью/перемещением работают за пределами одной строки.

altwazar ★★★★★
()
Ответ на: комментарий от micronekodesu

Потому что когда установка и подключение плагина в одном файле, его параметры в другом, а кейбиндинги в третьем это как-то не очень удобно оказалось. Да и искать что к чему и редактировать в случае одного файла проще.

Проще в разных файлах, только с удобным логическим разделением. Типа ./lua/plugins/плагин.lua и там связанные с этим плагином настройки и биндинги. Совсем простые плагины без каких-то настроек можно в один файл свалить типа остальное.lua.

altwazar ★★★★★
()
Ответ на: комментарий от Kroz

Нужно на Винде, поэтому терминал не вариант, только GUI.

nvim без проблем работает в windows terminal например.

Если все равно нужен отдельный гуй, то упомянутый тут neovide должен работать. Я пользовался https://github.com/RMichelsen/Nvy - тоже без проблем. Тащемта это была одна из главных целей форка neovim, разделить бэкенд с фронтендом и получить возможность создавать нормальные гуевые клиенты.

Lrrr ★★★★★
()
Ответ на: комментарий от Kroz

Я под виндой пользовался такими терминалами для нвима:

  • windows terminal: юзабельно, но есть пара «но». 1 - бага с кусором, который в режиме normal иногда почему-то становится тонким, как будто ты в insert. 2 - подвисает на секунду-две при переключении между русской и английской раскладкой (альт-шифт у меня).
  • wezterm - хорошо, вышеописанных wt-шных багов нет, но не работает undercurl, т.е. не видно подчеркиваний от vim.diagnostic. Говорят, в nightly уже работает, но не пробовал.
  • neovide - тоже хорошо, но совсем не работает shift-insert. У него вообще нет своих кейбиндингов, всё только нвим-овское. Не то, чтобы большая проблема, есть "+ и C-r +, но вот во всякие fzf-lua хрен чо вставишь из системного буфера.

В общем, пока сижу в neovide.

kokostek
()
Ответ на: комментарий от altwazar

В хеликсе подход область/перемещение(с выделением)->действие. Например, w - перемещает к началу следующего слова и выделяет область, затем d - удалит выделение.

Это интересно. На первый взгляд кажется даже удобнее.

bread
()

Хотя я их и не советую использовать, но об их существовании стоит упомянуть, так как они скорее служат для того, чтобы понять, подходит ли для тебя Vim/Nvim.

И все таки наблюдаю обратную тенденцию - не Helix ставят посмотреть, чтобы понять, подходит ли neovim, а наоборот, уходят на Helix, устав ковырять и настраивать разные плагины неовима.

l0stparadise ★★★★★
()
Ответ на: комментарий от Werenter

Мне в vim сильно не хватает всего одной вещи, из-за которой пришлось частично мигрировать на neovim — поддержки буфера обмена на wayland.

Поддержка клипборда пилится https://github.com/vim/vim/pull/17097

habamax ★★★
()
Ответ на: комментарий от l0stparadise

Именно так и перешел на helix. Плюс там гораздо проще освоить и начать реально пользоваться вим-моушенами и командами. Хотелось простой редактор который можно поставить и он просто работает.

altwazar ★★★★★
()

Спасибо за статью.

Несколько раз пытался перебраться на него для разработки на С++, и что-то не заходило, не получалось.

Может стОит ещё раз попробовать…

Какие плагины и настройки сейчас считаются популярными для C++ (разработка и отладка), можете линками покидаться?

Нужны:

  • навигация по дереву исходников (по классам не надо)
  • поиск, в т.ч. переходы из найденного на места вызова
  • переключение определение\реализация
  • отладка (точки останова, по шагам, значения переменных)
  • автодополнение

Проект на голых Makefile, довольно большой (не pet)

blex ★★★★
()
Ответ на: комментарий от blex
  • встроенные возможности lsp, а lsp встроенный…
  • встроенные возможности lsp
  • встроенные…
  • nvim-dap
  • nvim-cmp

скопируй мой репозиторий и отредактируй lsp.lua и dap.lua; в tree-sitter.lua добавь cpp… но я там еще не все реализовал из задуманного

rtxtxtrx ★★★
() автор топика
Ответ на: комментарий от blex

Какие плагины и настройки сейчас считаются популярными для C++

лично мое мнение - для neovim сейчас нет никакого смысла устанавливать кучу плагинов по отдельности. Сборки вроде nvchad содержат все базово нужное и легко расширяются/изменяются под свои нужды благодаря lua.

Установив nvchad, ты сразу получаешь из коробки навигацию (с помощью nvim-tree), fuzzy-поиск чего угодно (с помощью telescope) и легкую настройку LSP, после которой заработают автодополнение и go to definition.

Для LSP нужен соответствующий LSP-сервер. Для плюсов обычно применяется clangd. Он есть в репах дистров, если хочется какое-то портабельное решение (чтобы например закинул конфиг по ssh или на винду, и оно заработало) - то можно пользоваться mason, это такой менеджер двоичных пакетов для neovim.

Проект на голых Makefile, довольно большой (не pet)

чтобы clangd заработал с проектом, должна быть возможность сгенерить clang compilation database (compile_commands.json). Если система сборки это не поддерживает, то можно воспользоваться bear или какой-нибудь аналогичной тулзой.

отладка (точки останова, по шагам, значения переменных)

все это можно сделать с помощью протокола DAP (базовый плагин - nvim-dap), но по мне так это менее удобно чем если просто запускать софт под gdb или lldb. Хотя кому как.

Куда более полезный для меня плагин - overseer, чтобы запускать сборку в фоне.

Lrrr ★★★★★
()

Спасибо, надо попробовать что-ли. Я посмотрел из-за плеча коллеги, как у него эта штука в полном развороте работает. Вроде красиво, мне понравилось. Подсказочки вылетают где надо какие надо. Говорит, что конфиг пилил три дня с помощью всемирного разума.

gns ★★★★★
()

Ламеризм во все поля. Доказательство того, что любая кухарка может писать статьи. Правда, плохие.

Например, можно ложить все…

Я бы посоветовал ТС видюшки на выкладывать на мировой сборник обучающих видео, как было сказано в одном недавно удалённом топике. В видюшке такое прокатит. А на письме это выглядит по-селюковски.

debugger ★★★★★
()
Последнее исправление: debugger (всего исправлений: 1)

Модераторы, вы катом принципиально перестали в статьях пользоваться? Читать раздел «статьи» с этими простынями на главной на смартфоне невозможно! Скроллить приходится десятки экранов, и среди всех этих заголовков и подзаголовков легко пропустить конец одной статьи и начало следующей. Так трудно кат после первого абзаца поставить??

debugger ★★★★★
()
Последнее исправление: debugger (всего исправлений: 1)
Ответ на: комментарий от l0stparadise

уходят на Helix

В хеликсе режим virtualedit работает?

debugger ★★★★★
()
Ответ на: комментарий от CrX

А кинь ссылку на хорошую Мурзилку для чайников. Я посмотрел на то, как мой коллега использует nvim с плагинами в качество IDE. Не то что б понравилось, но заинтересовало. Не VSCode же, в самом деле. :)

gns ★★★★★
()
Ответ на: комментарий от gns

А кинь ссылку на хорошую Мурзилку для чайников

Не, сейчас не найду. Сам предпочитаю официальную документацию, но натыкался как-то, бывало на гораздо более полноценные гайды.

CrX ★★★★★
()
Ответ на: комментарий от gns

ну тут нету смысла писать какую-то статью уровня докторской диссертацию: гарантированно всякие умники засрут или того хуже ненужно-дебилы клоунов наставят, потому что ко-ко идея есть и больше ничего не нужно. боюсь, тебе нужна не статья, а целая книга по настройке nvim, да еще и lua выучить придется. но что точно:

  • nvim лучше vim и проще в настройке
  • lazy.nvim - единственный поддерживаемый менеджер плагинов
  • coc.nvim не нужен, так как lsp встроенный
  • cmp лучше чем встроенное автодополнение
  • nvim-treesitter обязателен. без него посветка работает, а вот, например, фолдинг - нет
  • lspconfig и mason нужны для настройки lsp. альтернатив им нет
  • для дебагга всего две опции: dap или vimspector
  • fzf-lua или telescope - для поиска по буферам и файлаи
  • spectre - для поиска и замены
  • остальное опционально. даже neo-tree не особо нужен так в nvim встроенный файловый менеджер
rtxtxtrx ★★★
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 2)
Ответ на: комментарий от debugger

Да, и правда нет катов, листать (но компе) неудобно. А смартфоны не нужны.

firkax ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.