Александър Иванов
cream в режим „expert“
29. Допълнение: само vim
Вече писах, че като посвикнете да работите с cream, с изненада ще установите, че се чувствате добре и във vim — било в терминала, било в конзолата без графична среда. И всичко, което дотук сте научили за режима „експерт“ на cream, ще работи.
Сега ще направя само няколко най-необходими разяснения и допълнения. За да не стане като в оня виц: „Седя във vim от години… Представа нямам как да изляза.“
Когато стартирате vim, напишете след командата името на файла, който ще редактирате:
$ vim my_text.txt
и натиснете Enter.
Vim ще изчете текста и ще ви го покаже в тъй наречения нормален режим на работа (Normal Mode). В този режим можете да разглеждате текста, но клавишите (от английската клавиатура!) въвеждат команди към редактора, а не въвеждат символи (текст). Може да преминете към вписване на текст така:
i — преминавате в режим за вписване на текст (режим Insert). Това се отбелязва в долния, информационния ред на редактора. Текстът, който пишете, ще „избутва“ надясно текста, който е в дясно от курсора. С натискане на клавиш Ins преминавате в режим Replace — текстът, който вписвате, ще „затъпква“, ще заменя текста вдясно от курсора. Следващото натискане на Ins ви връща към режим Insert.
С клавиш Esc се връщате към нормалния режим на работа — нормалният режим на работа е всъщност като режима „експерт“ в cream.
Може да влезете отново в режим Insert и със следните клавиши: I, a, A, o, O — експериментирайте, за да разберете какво правят.
Ама как да излезем от редактора?
С командата :q (очевидно, мнемоника от quit). Ако текстът ви не е променян или промените са записани, излизате от редактора без всякакви съобщения. Иначе редакторът ви съобщава, че текстът е променен и незаписан. Пред вас има две възможности.
С :wq ще запишете текста и ще излезете от редактора — w е мнемоника от write. Може да използвате командата и самостоятелно :w, за да записвате периодично промените в текста си. Не е лошо.
Но ако искате да излезете от редактора, без да записвате промените в текста, използвайте :q! Удивителният знак след командата означава ’изпълни командата безусловно’, тоест без предупреждения. Още един пример:
Искате да запишете текста си с ново име — :saveas my_new.txt — но получавате предупреждение от редактора, че файл с име my_new.txt вече има. С командата :saveas! my_new.txt ще запишете текста си във вече съществуващия файл и — разбира се! — ще загубите предишното му съдържание. Вие решавате. Съкратеният вариант на командата е :sav my_new.txt.
Редакторът vim може да работи с много текстове едновременно. Това се нуждае от малко разяснения.
Ако при стартирането на редактора подадете няколко имена на текстови файлове, разделени с шпация, те всичките ще се изчетат в различни буфери в паметта. Редакторът показва в прозореца си първият изчетен текст, останалите са „скрити“. С командата :buffers ще видите списък на заредените в паметта файлове. По-точно — вие виждате списък с имената на файловете, чието съдържание е заредено в буфери в оперативната памет. Например така:

От картинката се вижда, първо, че командата :ls е по-кратка форма на :buffers. Синоним на :buffers e и :files, откъдето става ясно и съкращението :ls. После, вижда се, че всеки буфер е номериран — тези номера не се повтарят и в документацията ги наричат идентификатори на буферите. С тези идентификатори може да се обръщате към един или друг буфер. Още тук, под списъка, може да напишете командата :b3 — с нея ще преминете към буфер с идентификатор 3, тоест към my_new.txt.
Ако текстът в буфера, който напускате, не е записан, ще получите предупреждение. Най-добре го запишете, преди да преминете към текста в друг буфер. Защото, ако безусловно напуснете този буфер (с !), ще загубите редакциите в него.
Между идентификатора (номера) на буфера и името на файла с буквени и небуквени символи се маркира информация за състоянието на буфера. В примера с a се отбелязва, че буферът е активен. Активен е буфер, чието съдържание е показано в прозорец. Символът % показва, че прозорецът на този активен буфер е на фокус. Защото vim поддържа множество прозорци, но, разбира се, само един от тях е на фокус. Вижте и картинката отдолу, на която са показани три отворени прозореца.
С # се отбелязва „алтернативният“ буфер, тоест буферът, който последно сте напуснали. В него може да отидете с Ctrl-^, тоест, между два текста, които сравнявате, може да се преминава с бързия клавиш Ctrl-^. Тук алтернативният буфер 1 е маркиран и със знак + — това означава, че съдържанието му е променено, текстът е редактиран и не е записан с промените. С буква h пък се отбелязва „скрит“ буфер (от hidden). И така нататък.

Повече разяснения има в помощната информация, която може да извикате с командата :help — в случая :help buffers. В някакъв момент сигурно ще поискате да я прегледате.
Помощната информация на vim е организирана чрез „хипертекстови“ препратки, означени с цвят. Когато отидете в раздела buffers, ще видите меню — когато поставите курсора на препратката след раздела 11. Using hidden buffers, например, и натиснете Ctrl-], ще отидете в този раздел. Може да се върнете обратно чрез Ctrl-O или Ctrl-T.
Може да затворите определен буфер с :bd <идентификатор>. По-разширени варианти на командата са :bdel и :bdelete. Ако в списъка буферът е маркиран със знак +, ще получите съобщение, че промените в него не са записани.
Разбира се, механизмът на undo и на redо е свързан с определен буфер, тоест „помни“ редакциите за определен текст. Отметките (marks) също са свързани с определен буфер. Отметките освен това се и запомнят, когато изтривате буфер.
Изобщо, vim (gvim, cream) поддържа подробен „протокол“ за всеки обработван от вас файл във .viminfo. Както виждате, това е „скрит“ файл, но може да го разгледате. Не го променяйте и не го изтривайте, ако не искате изненади.
Съществува още една команда за „изчистване“ на буфер — :bwipeout (:bwipe, :bw). Само че тя не записва в „протокола“ никаква информация, тоест отметките и локалните настройки за текста ви ще бъдат загубени. Хубаво е да знаете, че съществува, но надали ще ви се наложи да я използвате.
* * *
А сега — малко повече за прозорците.
Свикнали сме от други програми да не правим разлика между прозорец (на програмата) и буфер (текст, файл), та ни е трудно да си представим защо е нужно да правим тази разлика във vim.
Защото във vim може да държите текст в буфер в паметта, без задължително да го свързвате с прозорец, който да го показва на монитора. Дори такъв „невидим“ текст може донякъде да бъде редактиран. Може още да разделите прозореца на две, тоест на два прозореца, и в двата да показвате един и същи текст. В много ситуации това е доста удобно. Така vim дава възможности, които — да! — може да не използвате; ама когато ви потрябват, са налични.
Така :new разделя прозореца хоризонтално на два прозореца, :vnew разделя прозореца на две вертикално. С Ctrl-W x разменяте позициите на новосъздадените прозорци. Буферът, свързан с новия прозорец е безименен (отбелязва се с [No Name]) и е празен. Тук може да изчетете файл с командата :e (:edit), например :e my_new.txt. Но може да използвате и командата :e. — тя отваря вградения във vim файлов менажер и може да си изберете файл от списъка:

На картинката основният прозорец е „разцепен“ на четири „подпрозореца“. Горе вляво е прозорецът с помощната информация; долу вдясно е файловият менажер. Текстовете са омацани с червено, защото е пусната правописната проверка за български език. Припомням, че може да я изключите със :set nospell.
Името на файла, чийто текст се редактира в един или друг прозорец, е изписано отдолу, под прозореца. Марката [RO] е от read-only: това са файлове, които не могат да се редактират — помощната информация, файловия менажер.
Командният ред е един — най-долу, но командите, които въвеждате тук, се отнасят за текста в прозореца, който е на фокус. В него е и курсорът.
Можете да сменяте фокуса, тоест да определяте в кой прозорец ще е курсорът, със следните команди:
Ctrl-W w и Ctrl-W W — променят фокуса на прозорците „в кръг“.
Ctrl-W l — (това е малка латинска буква ел) фокусът се премества на прозореца вдясно;
Ctrl-W h — фокусът се премества на прозореца вляво;
Ctrl-W j — фокусът се премества на прозореца отдолу;
Ctrl-W k — фокусът се премества на прозореца отгоре.
Всички тези действия се извършват, разбира се, само ако има съответен прозорец, но не дават грешка, ако няма.
Забелязвате вече, че повечето действия с прозорци се извършват с команда с префикс Ctrl-W (мнемоника за window), а следващите клавиши отговарят на клавишите за движение на курсора из текста. Клавишните комбинации във vim са доста смислено организирани и като схванете логиката, не са трудни за запомняне.
С командите :split (:sp или Ctrl-W s) и :vsplit (:vs или Ctrl-W v) „разцепвате“ на две прозореца, в който работите — в новия прозорец се вижда същият текст (буфер). И като редактирате текста в единия прозорец, редакциите се отразяват и в другия — нали все пак редактирате един и същи текст (буфер).
С командата :hide може да затворите прозорец, а буферът (текстът), свързан с него, става скрит (hidden). С командата :ls ще го виждате и може да го възстановите в прозорец. С командата Ctrl_W o (от only) активният прозорец заема целия екран. Другите буфери стават неактивни, но се съхраняват в паметта.
С натиснат ляв клавиш на мишката „хванете“ границата между два прозореца или информационния ред на горния прозорец — ще можете да променяте размера на прозорците — вляво и вдясно, нагоре и надолу. Разбира се, тези действия могат да се извършват и с бързи клавиши.
Пък някой път, като имате време, проявете любопитство, погледнете и документацията. Тя е добре структурирана и изчерпателна.
И сега — още малко коментар за командата :q. Ако работите с един прозорец и с един буфер, с командата :q просто излизате от програмата. Ако работите с повече прозорци, командата :q затваря активния прозорец и буфера, свързан с него, а фокусът се пренася върху следващият прозорец (и буфер). И така нататък, докато затворите последния прозорец (и буфера, свързан с него). Така обикновено излизате и от програмата.
Но ако затваряте последния прозорец, а в програмата има скрити или неактивни буфери, несвързани с прозорец, ще получите съобщение за грешка — вие трябва да решите какво ще правите с данните в тези буфери.
Цялата тази процедура може да съкратите с комбинираната команда :qa (a е от all) — програмата затваря всички прозорци и всички буфери и излизате от нея. Ако някъде има незаписани данни, пак ще получите съобщение — умна програма, пази труда ви от собствената ви глупост.
* * *
И да кажа няколко думи за табулираните страници (tab pages), които vim също поддържа.
Вие виждате табулирани страници в интернетския си браузър. Когато отворите няколко интернетски страници, виждате, естествено, само една от тях. Другите страници са представени в горния ред на екрана чрез „етикетчета“, показващи заглавието на страницата. Тази практика в компютърния дизайн отново стъпва върху практиката на библиотеките. Там в чекмеджето с фишове можеше да се поставят разделители — по-твърди картончета, изрязани така, че над фишовете да стърчи „езиче“, на което се отбелязва името на раздела. Разделителите се подбираха така, че „езичетата“ им да бъдат отместени по хоризонтала и да не се застъпват, за да се вижда текстът върху тях, дори ако са много близко един до друг.
Ако стартирате vim така:
$ vim -p my_text.txt my_new.txt
ще се изчетат двата текста в отделни табулирани страници — това е смисълът на флагът -p.
Работата е там, че във vim всяка табулирана страница представлява „основен“ прозорец — вие може да го делите на подпрозорци и да изчитате в тях различни буфери (текстове). Така може да създавате твърде сложни структури от работни текстове. По моему, по-сложни, отколкото ще ви е необходимо.
Между табулираните страници може да преминавате с клавишните комбинации Ctrl-PgUp и Ctrl-PgDw. Ако не става, пробвайте с клавишите PgUp и PgDw от калкулаторната клавиатура. И най-накрая — мишката обикновено работи.
Повече информация за това има в документацията :help tabpage.
* * *
Добре, нека сега да кажа няколко насочващи думи, как във vim да извършвате „масови редакции“, тоест как да извършвате редакции в много файлове.
С :bufdo <команда> командата се изпълнява във всички заредени в редактора буфери. С | може да се добави втора, трета команда. Сигурно се сещате, че | е операторът за конвейерна обработка в конзолата с командния интерпретатор на системата.
Ето един реален пример: на някакъв етап от обработките на текста на „Под игото“ установявате, че има грешка с пълния член в израза „че народния дух е приготвен“. Прозяпали сте го, когато сте правили добре редактирания текст (вж. Добре редактиран текст). Ама междувременно сте направили още десетина файла — с разделение на диалог и монолог, със списъчно представен текст, с разни индекси.
Проверките ви, за щастие, показват, че лексата „народния“ се среща еднократно в текста. Значи може да заредите във vim всичките си работни файлове и да направите:
:bufdo %s:народния:народният: | update
В командата за заместване няма нищо ново. Тук даже не е необходимо да се използва флагът g (global), защото знаем — лексата се среща еднократно. Новото е във втората команда update — тя прилича на :write (:w), но записва текста от буфера, само ако е променен.
А защо е необходимо да я използваме? Спомнете си, че ако се опитаме да напуснем буфер, който е редактиран, но промените не са записани във файла, получаваме съобщение за грешка. Значи изпълнението на нашата „комплексна“ команда ще спре с грешка още при опита на програмата да напусне първия редактиран буфер и да премине към втори. Ето затова при масови редакции е необходимо да се използва и командата :update (:up).
С командата :windo се правят масови поправки във всички буфери, които са в отворен прозорец. С командата :tabdo — във всички табулирани страници. За повече информация погледнете документацията, потърсете и примери в интернет — примерите в интернет обикновено са по-нагледни. И най-вече — експериментирайте!
Моят пример с „Под игото“ не е измислен — проверете!
Изтеглете си от chitanka.info текста на Под игото и проверете. (Аз се надявам, че никой от екипа на Читанката не е толкова любознателен и трудолюбив, че да прочете този мой текст и да оправи тази, всъщност — незначителна, грешка.)
Но за глотометриста нещата лесно могат да станат по-сложни.
Представете си, че в текста „народния“ се среща няколко пъти. Очевидно се налага да увеличите контекста, например, да потърсите „народния дух“ и да се убедите, че изразът се среща само веднъж.
Но вие вече сте създали и файлове със списъчно представен текст, може дори да сте приписали и класификатори, например:
народния<tab>A
дух
Отбелязал съм табулатора с <tab>, за да се вижда.
И командата за заместване става малко по-сложна:
:bufdo %s:народния\([ \tA\n]\+дух\):народният\1: | update
Убедете се, че разбирате защо трябва да се използва множителят \+ и как работи групирането.
* * *
Сега искам да покажа няколко възможности на vim да работите успоредно с няколко копия на текста.
Това е възможност, която често е полезна в глотометричните обработки. Например, вие сте се придържали към моите съвети да запазите текста си в списъчно представяне и да го копирате в отделни файлове, в които отбелязвате само една глотометрична характеристика.
Искате да прегледате два или повече такива файлове — така може да проследявате грешки или да допълвате информация.
Може да си разделите екрана на vim на две или повече екранчета вертикално и във всяко от тях да изчетете съответния текст. Картинката отдолу показва точно такава ситуация.

Ако стартирате vim с -О, редакторът сам ще създаде вертикален прозорец за всеки файл.
Вероятно ще разпознаете текста — началото на Елин-Пелиновата „Напаст божия“. Ще забележите, че синтактичната главна буква е премахната и че са наслагани класификатори в отделните файлове за лични глаголи, за прилагателни и за съществителни имена. Използвал съм търсене (с /\t.$), за да ги оцветя, да се виждат по-добре.
Трите текста в момента са подравнени ред за ред. И тук vim ни дава удобната възможност да ги „закопчеем“ един за друг, така че като прелистваме единия текст, да се прелистват и другите текстове и подравняването на редовете да се запазва.
Това става с командата :set scrollbind или съкратения й вариант :set scb. „Разкопчаването“ на прозорците става с удивителен знак след командата :set scb!.
Обаче командата :set scb трябва да се приложи към всеки един прозорец, който искаме да „закопчеем“. Например, може да обвържете два от прозорците, а останалите да оставите свободни. Ако пък искате да „закопчеете“ текста във всички прозорци, груповата команда windo е точно за това:
:windo set scb
Ако стартирате vim с „ключе“ -d или използвате командата vimdiff, за да изчетете няколко уж еднакви файла, редакторът ще ви покаже разликите между текстовете:

Както виждате, текстовете се изчитат във вертикални прозорци и са „закопчани“, тоест може да ги прелиствате успоредно. С команда do приемате промяната от съседния (неактивния) прозорец, с команда dp прехвърляте промяната от активния прозорец в неактивния. С ]c и [c може да обхождате редовете, маркирани като различни.
Ако в резултат от редакциите редакторът загуби информацията за различията, използвайте командата :diffupdate, за да я възстановите.
Когато стартирате vim в този режим (diff-mode), по подразбиране дългите редове не се пренасят в края на прозореца. Това е удобно при сравняване на програмни текстове или списъци, където редовете не са много дълги, и е неудобно при сравняване на нормален текст. Но винаги може да използвате командата
:windo set wrap
Когато има повече еднакви редове, vim ги „сгъва“ (folding) — със знак + в началото на реда и с число се показва колко реда са „сгънати“. Като поставите курсора на такъв ред, със zo (от open) може да „разгънете“ редовете, а със zc (от close) да ги „сгънете“.
За повече информация:
:help diff-mode
* * *
За vim има десетки хиляди сценарии (scripts), написани най-вече на вградения Vimscript (VimL). Вижте, например, сървъра Vim Awesome. Нужно ли е да припомням, че и cream представлява пакет от такива сценарии?
Така че с такива програмки (сценарии) може да допълвате и без това огромните възможности на vim.
Два начина има да инсталирате такива приставки (plugins) — „ръчно“ или чрез програма, която помага да управлявате приставките (plugin manager). Вижте, например, този преглед на програми за управляване на приставките: What are the best plugin managers for vim?
Първо ще инсталирам „ръчно“ програмата за управляване на приставките vim‑plug: 1) във вашата домашна директория създайте директории .vim/autoload — не пропускайте точката пред .vim; ако сте в Windows (в PowerShell), създайте $HOME\vimfiles\autoload; 2) копирайте файла plug.vim в /autoload.
Готово. Стартирайте vim и изпълнете командата :PlugUpgrade — тя проверява дали има обновления на vim‑plug и (ако има) го обновява.
Приставките (plugins), с които работи vim‑plug, се описват във файла .vimrc — ако го няма, създайте го; ако го има, допишете в него, например, следното:
" " My .vimrc " call plug#begin() Plug 'preservim/NERDTree' Plug 'preservim/tagbar' call plug#end() nmap <F8> :TagbarToggle<CR> nnoremap <F7> :NERDTreeToggle<CR>
В Windows името на файла трябва да бъде _vimrc и той трябва да бъде или в потребителската ви директория, или в общата за системата директория C:\Programs Files (x86)\Vim.
С реда call plug#begin() се отваря списъкът с приставките. В скобите може да се определи (с единични кавички) директория, в която те да се инсталират: по подразбиране директорията е '~/.vim/plugged'. Приставките се въвеждат с команда Plug и пак в единични кавички. В примера се подразбира, че те се вземат от сървъра GitHub; ако ги вземате от файл или от друг сървър, трябва да изпишете пълния път до тях. И както вече сигурно се досещате, списъкът завършва с реда call plug#end(). В последните два реда просто свързавам показването и скриването на двете приставки с клавишите F7 и F8.
Приставката NERDTree предоставя файлов менажер, може би малко по-удобен от стандартния за vim (:e.); tagbar е полезна за пишещите програми: тя „картира“ програмния текст, като показва модулите, класовете, обектите, методите, функциите и пр. и дава възможност на програмиращия бързо да се придвижва из текста на програмата си. Но приставката vim-plug разчита да е инсталиран пакетът git, а приставката tagbar ще работи само ако е инсталиран пакетът ctags (в Debian и Ubuntu — exuberant-ctags).
Сега стартирайте vim и изпълнете командата :PlugInstall — тя ще инсталира всички приставки, включени във .vimrc. С :PlugUpdate се извършва обновяване на приставките (ако има обновяване на GitHub). След обновяването с :PlugDiff може да видите разликите с предишния вариант на програмата.
И ето картинка:

Тук използвам за графичен терминал terminator, „разцепил“ съм прозореца му на две и в горния, по-големия прозорец съм стартирал vim с някакъв програмен текст. Вляво се вижда файловият менажър NERDTree (може да се скрие с F7), вдясно е картиращата приставка tagbar (може да се скрие с F8). Получила се е твърде удобна за работа комбинация от програмни средства.
Във vim от серията 8 е развита нова система за добавяне на „пакети“, тоест на директории, в които има една или повече приставки (plugins). По въпроса може да прочетете повече в документацията (:help packages) или, например, в този по-разказвателен текст: How to install Vim plugins.