Pull to refresh

Жизнь в консоли или как я полюбил боль

Level of difficultyEasy
Reading time8 min
Views6.4K

Всем привет!
Не судите строго, это моя первая статья не только на Хабр, но и в целом для ИТ мира
Немного о себе - зовут меня Сергей, я начинающий разработчик на С++, большой любитель программирования, 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 - цветовая схема. Использую ее не первый год, начал еще во времена работы в QtCreator

  • neoclide/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 пободный режим, в каждом современном редакторе кода имеется встроенный терминал, стандартные терминалы вроде и так хорошо кастомизируются, да и многие операции можно сделать не прибегая к его помощи. Но всё же плюсы имеются, и причем довольно весомые:

  1. Минимизация ненужных функций - в моей среде есть только самое необходимое, только то, что мне понадобилось. IDE всегда предоставляет самый большой набор команд, скрытый в недрах менюшек, хоткеев и команд и чтобы научиться этим пользоваться необходимо пройти 10 туториалов. Всё это круто, НО это всё придумали крутые прогеры для крутых прогеров, а когда ты не пишешь одной ногой со скорость 10 000 символов в минуту, такое изобилие тебе мешает ну или как минимум не очень помогает

  2. Изучение командной строки - когда за тебя никто и ничего не делает, будь то глобальный поиск про проекту, поиск файлов в проекте, создание нового класса, запуск и конфигурация проектов, тебе приходится делать это самому и тут ты начинаешь искать инструменты, которые тебе доступны в командной строке, писать для удобного использования скрипты, или или углубленно изучать уже знакомые утилиты. Всё это прокачивает тебя как разработчика, еомандная строка есть везде, и стандартные утилиты (они как правило на всех unix-based одинаковые) тоже

  3. Ну и конечно внимание со стороны колег и знакомых. Как же люди дуреют, когда видят всё это сочетания - nvim запущенный в сессии tmux с обилием вкладок, всё это происходит в нестандартном терминальном эмуляторе. Как они столбинеют, когда ты навигируешься на hjkl, как недоумевают при виде поиска по проекту с помощью grep в терминале

Всем спасибо!

Tags:
Hubs:
+10
Comments51

Articles