Всем привет!
Не судите строго, это моя первая статья не только на Хабр, но и в целом для ИТ мира
Немного о себе - зовут меня Сергей, я начинающий разработчик на С++, большой любитель программирования, Linux и консоли! Именно о последнем мы сегодня и поговорим. Я родился в эпоху повсеместного существования GUI, массивных IDE и всего прочего, и как многие молодые пользователи всегда не любил консоль, даже поступив в ВУЗ на программиста
Моё знакомство с ИТ
Моё знакомство с ИТ и программированием началось в школе на уроках информатики - мы писали небольшие странички с помощью HTML, маленькие алгоритмические задачи на Pascal, но затем нам показали мир разработки приложений с GUI - дивный мир Lazarus, вот это разорвало моё видение мира. Затем я поступил в ВУЗ, и просто по стечению обстаятельств и крутому названию выбрал направление Информатика и Вычислительная Техника, где я познакомился с С++, и влюбился (но статья не об этом). С самого начала мы пользовались IDE и практически не погружались в дебри командной строки | а зря! |, сборка и конфигурирование всегда происходило из GUI, переменные сборки добавлялись в табличку, там же проверялись, сборка происходила по нажатию магической кпоки зеленого треугольничка, изредка отправляясь в консоль для того, чтобы сделать коммит. И я долгое время около 2х лет искренне верил, что это так и надо, моим основным инструментом был QtCreator, основной единственной ОС была Windows 10. Но затем в мою жизнь ворвался ОН!
Прыжок в мир символов
Устроившись на свою первую она же единственная работу, я увидел, что мой тимлид пользуется neovim, в качестве основного редактора кода, cmake использует через консоль, по ФС перемещается там же... Меня это повергло в шок. Справедливости ради я уже какое-то продолжительное время пользовался Ubuntu в качестве основной ОС, по ошибке несколько раз открывал neovim и к работе с терминалом был немного приучен, но чтобы всю работу выполнять в нем!? НЕТ УЖ! Но по долгу службы пришлось много проектов собирать из исходников и каждый раз открывать QtCreator для этого - желания не нашлось. И сначала я привык пользоваться cmake через терминал, затем познакомился поглубже научился выходить с nvim, после чего узнал о существовании такой чудесной штуки как tmux и в какой-то день из чистого любопытства ну и необходимости работать внутри контейнера, не поднимая 10 инстансов QtCreator решил узнать - а зачем мой лид так страдает, что же там такого сладкого? Оооо! Если бы я только тогда знал, куда меня это заведёт...
Как это было
Решив, что я хочу попробовать переползти в консоль, я начал пользоваться nvim - это было больно! Очень! Переход на hjkl
навигацию, переключение между режимами, намеренный отказ от мышки (так рекомендуют трушные прогеры в интернетах), изучение всех многочисленных команд, практические полное отсутствие подсветки синтаксиса, нормального дополнения кода и просто консоль! Но мне на помощь пришла долгая поездка по поезде (суммарно туда обратно 2е суток чистого пути), где из развлечений было только изучение nvim. Когда руки освоились жить с клавиатурой, перестали при любой непонятной ситуации бежать и дёргать мышь, nvim стал раскрываться по новому - навигация ускорилась, руки постоянно готовы нажимать, так как не уходят с клавиатуры, каждое твоё действие становится обдуманным! - nvim может тебе не простить промаха, 2 раза спрашивать и предлагать красивую менюшку он не будет, ты перестаешь путаться в изобилии встроенных функций в разных IDE, используешь только те, что тебе нужны и ищешь их, только когда они нужны.
Плагины = всемогущество
Победив базовые функции nvim, я захотел больше удобства - дерево файлов, автокомплит, подсветка синтаксиса, диагностика ошибок - в общем всего того, что в IDE идёт по умполчанию (но почему кто-то может решать что мне нужно!?). И тогда я открыл для себя мир плагинов - по свяким статья в интернете выбрал для себя vim-plug
и начал пробовать и искать для себя то самое. Сразу предостерегу от использования vimscript
для написания конфигурации, самые свежие и интересные плагины на данный момент пишутся на lua
, да и официальные плагины от разработчиков nvim
. И в конце концов пришёл к такой конфигурации:
-- ~/.config/nvim/init.lua
-- Set encoding and colors
vim.opt.encoding = 'utf-8'
vim.opt.termguicolors = true
vim.cmd('set t_Co=256')
-- Enable lines number
vim.wo.number = true
-- Enable line wraping
vim.wo.wrap = true
-- Enable show mode in status bar
vim.opt.showcmd = true
-- Highlight cursor line
vim.wo.cursorline = true
-- Enable showing mode in status line
vim.opt.showmode = true
-- Setting tabs and indentation
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.softtabstop = 4
vim.opt.expandtab = true
vim.opt.autoindent = true
vim.opt.smarttab = true
-- Set background color
vim.opt.background = 'dark'
-- Set fixed column for text alignment
vim.opt.colorcolumn = '80'
-- Enable file type indentations
vim.cmd('filetype indent on')
-- Set terminal to fast
vim.opt.ttyfast = true
-- Plugins
local Plug = vim.fn['plug#']
vim.call('plug#begin')
Plug('Mofiqul/dracula.nvim')
Plug('neoclide/coc.nvim', { ['branch'] = 'master', ['do'] = 'npm ci'})
Plug('nvim-treesitter/nvim-treesitter')
Plug('nvim-tree/nvim-web-devicons')
Plug('nvim-tree/nvim-tree.lua')
Plug('nvimdev/indentmini.nvim')
vim.call('plug#end')
-- End Plugins
-- Plugins setup
-- TreeSitter setup
require'nvim-treesitter.configs'.setup{
ensure_installed = { "c", "cpp", "lua", "python", "bash" },
auto_install = true,
highlight = {
enable = true
}
}
-- NvimTree setup
require("nvim-tree").setup()
-- IndentMini
require("indentmini").setup{
exclude = {'lua', 'xxx'},
minlevel = 2
}
-- Set colorscheme
vim.cmd('colorscheme dracula')
-- FileType specific settings for C and C++ files
vim.api.nvim_create_autocmd("FileType", {
pattern = {"c", "cpp", "h", "hpp"},
callback = function()
require("indentmini").setup{
exclude = {'lua', 'xxx'},
only_current = true,
minlevel = 2
}
vim.api.nvim_buf_set_keymap(0, 'n', 'gh', ':CocCommand clangd.switchSourceHeader<CR>', {noremap = true, silent = true})
end
})
--End Plugins setup
-- Key mappings
-- Insert mode mappings
vim.keymap.set('i', '<C-Space>', 'coc#refresh()', {silent = true, expr = true})
vim.keymap.set('i', '<CR>', 'coc#pum#visible() ? coc#pum#confirm() : "<CR>"', {silent = true, expr = true})
-- Normal mode mappings
vim.keymap.set('n', 'gd', '<Plug>(coc-definition)', {silent = true})
vim.keymap.set('n', 'gy', '<Plug>(coc-type-definition)', {silent = true})
vim.keymap.set('n', 'gi', '<Plug>(coc-implementation)', {silent = true})
vim.keymap.set('n', 'gr', '<Plug>(coc-references)', {silent = true})
vim.keymap.set('n', '[g', '<Plug>(coc-diagnostic-prev)', {silent = true})
vim.keymap.set('n', ']g', '<Plug>(coc-diagnostic-next)', {silent = true})
-- Winresize mapping
-- Vertical
vim.keymap.set('n', '<M-j>', ':wincmd 5-<CR>', {noremap = true, silent = true})
vim.keymap.set('n', '<M-k>', ':wincmd 5+<CR>', {noremap = true, silent = true})
-- Horizontal
vim.keymap.set('n', '<M-h>', ':wincmd 10<<CR>', {noremap = true, silent = true})
vim.keymap.set('n', '<M-l>', ':wincmd 10><CR>', {noremap = true, silent = true})
-- Additional normal mode mapping
vim.keymap.set('n', '<F2>', ':NvimTreeToggle<CR>', {silent = true})
vim.keymap.set('n', '<C-/>', '<leader>c<space>', {silent = true})
vim.keymap.set('n', 'K', ':call CocActionAsync(\'doHover\')<CR>', {silent = true})
Опишу только самое интересное, самое начало - базовая настройка, с этим справится каждый и примеров в интеренете море. Блок с плагинами:
Mofiqul/dracula.nvim
- цветовая схема. Использую ее не первый год, начал еще во времена работы в QtCreatorneoclide/coc.nvim
- фундаментальный плагин в миреnvim
. Нужен для таких вещей как автодополнение, inlayHint и кучи других фишек (я до конца его так и не изучил). У меня он собирается из исходников сmaster
ветки, потому что я хочу иметь самый свежий код этого плагина. Для его лучший работы необходимо устанавливать дополнительные внутрнении расширения, дляC++
отлично подходитcoc-clangd
, для работы сcmake
-coc-cmake
. Список огромент и найти его можно в оф. репозитории проектаnvim-treesitter/nvim-treesitter
- плагин для расширенной подсветки синтаксиса. Без него встроенная подсветка крайне скуднаnvim-tree/nvim-web-devicons
- плагин для разных иконок в интерфейсе, чисто визуалnvim-tree/nvim-tree.lua
- расширение, которое добавляет боковое дерево в навигацией по ФС. Удобно, если в проекте больше 2-3 файлов и имеется сложная вложенная структураnvimdev/indentmini.nvim
- плагин, который добавляет линию идентификации вложенности кода, показывает, на какой глубине твоя конкретная строка
Многие из этих плагинов совместимы с моей цветовой схемой, но такую поддержку имеют не все плагины и цветовые схемы. Если вы планируете использовать что-то другое - лучше проверить их совместимость
Далее настраиваем плагины:
nvim-treesitter
- настраиваю список языков, для которых необходимо проверять наличие установленных модулей, включаю для них атвоматическую установку и по умолчанию включаем подсветкуnvim-tree
- просто включаемindentmini
- настраиваем файлыlua
, в качестве исключения и устанавливаем минимальный уровень 2, мне просто не нравится когда лишняя линия идёт
А так же добавляем специфичные настройки для C++
файлов:
Дополнительный мапинг переключения между заголовочником и исходным файлом по
gh
командеПеренастройка
indentmini
- вC++
проектах мне больше нарвится, когда показана вложенность не во всём файле, а только конкретной строки
Глубже, только глубже
Живость?
Как уже было сказано, одной из причин моего перехода на nvim
стало использование контейнеров, а в них никого рабочего стола - только консоль, только удовольствие, а встроенный GnomeShell
мне не очень нравился - странный дизайн, странная настройка доступная через гуи, но лучше всё таки файлики вручную. Немного посомтрев интернет и Хабр в частности, нашёл я Alacritty
- лёгкий, минималистичный, шустрый, настройка только через консоль - всё как и хотел. Минимальная настройка и вуа-ля. Файл конфигурации:
# ~/.config/alacritty.toml
import = [
"~/.config/alacritty/catppuccin-mocha.toml"
]
[font]
normal = {family = "MonaspiceNe NFM", style = "Regular"}
[env]
TERM = "xterm-256color"
Здесь расказать особо нечего - настроил цветовую схему, подходящую под мою любимую dracula
, взял nerd шрифт, чтобы отображались красивые значки и задал переменную окружения, для нормального отображения цветов
Навалим удобства
Стоило бы на этом моменте уже остановиться погружаться так глубоко в недры терминальный жизни, НО НЕТ! Для завершения нам нехватает всего одного шага, но очень важного
Так как работа проходит в контейнере, а для каждого действия запускать отдельный терминал и входить в новую сессию bash
- долго, нудно, неудобно и вообще держать 10 открытых окон alacritty
(он не поддерживает табы и сплит)? И тут на работе я узнаю про утилиту tmux
- консольный мультиплексор - программа, позволяющая создавать нужное число вкладкок, давать им имена, копировать текст из консоли в системный буфер и рулить всем этим не открывая рук от клавиатуры - ВЕЛИЧИЕ!
Его настройка тоже довольна тривиальна:
set -g default-terminal "xterm-256color"
set-option -ga terminal-overrides ",xterm-256color:Tc"
set -g status-bg colour0
set -g status-fg colour7
Рассказывать о конфигурации особо нечего, задаю нужные опции для корректного отображения цветов и символов, а так же меняю цвет статусбара, чтобы визуально отличать хостовую сессию (статусбар темный) от сессии в контейнере (в рабочем образе я добавил этот же файл, только с другим цветом - синий), или от сессии на рабочех серверах (там стандартный зелёный цвет)
Вот такой получился мой путь в мир консоли
И зачем?
Пожалуй самая важная часть всей этой сатьи - зачем всё это?
По большому счёту - не за чем, во многих современных IDE есть vim пободный режим, в каждом современном редакторе кода имеется встроенный терминал, стандартные терминалы вроде и так хорошо кастомизируются, да и многие операции можно сделать не прибегая к его помощи. Но всё же плюсы имеются, и причем довольно весомые:
Минимизация ненужных функций - в моей среде есть только самое необходимое, только то, что мне понадобилось. IDE всегда предоставляет самый большой набор команд, скрытый в недрах менюшек, хоткеев и команд и чтобы научиться этим пользоваться необходимо пройти 10 туториалов. Всё это круто, НО это всё придумали крутые прогеры для крутых прогеров, а когда ты не пишешь одной ногой со скорость 10 000 символов в минуту, такое изобилие тебе мешает ну или как минимум не очень помогает
Изучение командной строки - когда за тебя никто и ничего не делает, будь то глобальный поиск про проекту, поиск файлов в проекте, создание нового класса, запуск и конфигурация проектов, тебе приходится делать это самому и тут ты начинаешь искать инструменты, которые тебе доступны в командной строке, писать для удобного использования скрипты, или или углубленно изучать уже знакомые утилиты. Всё это прокачивает тебя как разработчика, еомандная строка есть везде, и стандартные утилиты (они как правило на всех unix-based одинаковые) тоже
Ну и конечно внимание со стороны колег и знакомых. Как же люди дуреют, когда видят всё это сочетания -
nvim
запущенный в сессииtmux
с обилием вкладок, всё это происходит в нестандартном терминальном эмуляторе. Как они столбинеют, когда ты навигируешься наhjkl
, как недоумевают при виде поиска по проекту с помощьюgrep
в терминале
Всем спасибо!