Links
https://danielmiessler.com/study/vim/#gs.Xg9jNGw
https://www.labnol.org/internet/learning-vim-for-beginners/28820/
https://gist.github.com/theotherzach/5033931
Минимум один трюк Vim, про который вы не знали
Recipes
" spaces to tabs %!unexpand -t 2 --first-only " tabs to spaces set tabstop=2 shiftwidth=2 expandtab :retab " объединяем строки через запятую или запятую с пробелом " https://vi.stackexchange.com/a/4149/26373 :'<,'>s/\n/,/ :'<,'>s/\n/, / " Rails.vim - кандидат на альтернативный файл " можно использовать для создания нового файла :echo rails#buffer().alternate_candidates()
# --- vim as default editor sudo update-alternatives --config editor
.gitignore
# Swap [._]*.s[a-v][a-z] [._]*.sw[a-p] [._]s[a-rt-v][a-z] [._]ss[a-gi-z] [._]sw[a-p] # Session Session.vim Sessionx.vim # Temporary .netrwhist *~ # Auto-generated tag files tags # Persistent undo [._]*.un~
Commands
View
| Command (via :set) | Description | 
cursorline | подсветка текущей строки | 
hls | Подсветка поискового запроса | 
list | Отображение непечатных символов | 
number | отображение номеров строк | 
Buffer Navi
| Command | Decsription | 
| NORM | |
:Exp | Эксплоер | 
| + | На первый символ следущей строки | 
| - | На первый символ предыдущей строки | 
| Ctrl+g | Отображение информации о текущем расположении курсора | 
| Ctrl+e | Прокручивание на одну строку вниз | 
| Ctrl+y | Прокручивание на одну строку вверх | 
| Ctrl+d | Вниз на полстраницы | 
| Ctrl+u | Вверх на полстраницы | 
| Ctrl+f | Вниз на страницу | 
| Ctrl+b | Вверх на страницу | 
| Ctrl+o | Перейти на предыдущую позицию в истории переходов | 
| Ctrl+i | Перейти на следующую позицию в истории переходов | 
| Ctrl+j | Перейти по гиперссылке | 
| Ctrl+t | Перейти назад по истории переходов по гиперссылкам | 
:e %:h/filename | Открыть (создать) файл filename в текущей директории | 
Clipboard
| Command | Decsription | 
p  | вставляем из буфера после курсора | 
| P | (заглавная p) вставляем из буфера перед курсором | 
| yyp или Yp | Дублировать строку | 
| "ay | Скопировать текст в буффер a | 
| "ap | Вставить текст из буффера a | 
| "+y | Копировать в системный буфер обмена | 
Editing
| Command | Decsription | 
i  | Переход в режим редактирования. Курсор остается на месте | 
| I | Заглавная i. Переход в режим редактирования. Курсор переходит в начало строки. | 
| a | Переход в режим редактирования. Курсор переходит на следующий символ. | 
| A | Переход в режим редактирования. Курсор переходит в конец строки. | 
| o | Переход в режим редактирования с созданием пустой строки ниже. Курсор переходит на новую строку. | 
| O | Заглавная o. Переход в режим редактирования с созданием пустой строки выше. Курсор переходит на новую строку. | 
| s | Переход в режим редактирования с удалением текущего символа. | 
| Ns | Удаление N-символов и переход в режим редактирования | 
| S | Переход в режим редактирования с удалением строки. | 
| rx | Заменить символ под курсором на символ x | 
R | Переход в режим замены | 
| cc | Удаление строки, переход в режим редактирования и отступ | 
| c$ | Удаление от курсора до конца строки и переход в режим редактирования | 
| ce | Удаление символов от курсора до конца слова и переход в режим редактирования | 
| di) | Удаление символов между скобками | 
| di" | Удаление символов между кавычками | 
| ddp | Удаление строки и вставка ее ниже следующей (смена строк) | 
| u | Отмена изменений, сделанных крайней командой | 
| U | (заглавная u) Отмена крайних изменений в строке | 
Find
| Command | Description | 
fx  | Поиск далее по строке символа x | 
| 2fx | Поиск второго символа х в строке | 
| tx | Поиск далее по строке символа xx с установкой курсора перед ним | 
| Fx | Поиск назад по строке символа x | 
| Tx | Поиск назад по строке символа x с установкой курсора перед ним | 
| * | Поиск всех вхождений слова под курсором | 
| # | Поиск всех вхождений слова под курсором (в обратном направлении) | 
/text | Поиск | 
?text | Поиск в обратном направлении | 
| n | Переход к следующему совпадению | 
| N | Переход к предыдущему совпадению | 
Visual Mode
| Command | Description | 
v  | включаем визуальный режим | 
| V | строчное выделение | 
| y | копируем выделенное | 
| d | вырезаем выделенное | 
| u | преобразование в нижний регистр | 
Windows
| Command | Description | 
Ctrl+g  | Отображение информации о позиции в файле | 
| Ctrl+wr | поменять местами компоновку | 
| Ctrl+ww | переключение курсора между буферами компоновки | 
| Ctrl+w_ | максимизировать окно | 
| Ctrl+w= | выровнять окна | 
| Ctrl+wc | закрыть текущее окно | 
| Ctrl+wH | переключение горизонтальной в вертикальную компоновку | 
| Ctrl+wJ | переключение вертикальной в горизонтальную компоновку | 
Tabs
| Command | Description | 
$vim -p file1 file2 | открываем vim с вкладками | 
:tabn file3 | открываем файл file3 в новой вкладке | 
:tabf index* | открываем файл с шаблону имени | 
:tabn(или gt)  | следующая вкладка | 
| gT | предыдущая вкладка | 
| igt | перейти на i-ую вкладку | 
:tabfirst | первая вкладка | 
:tablast | последняя вкладка | 
:tabs | список вкладок | 
:tabm X | перемещаем текущую вкладку на позицию Х+1 | 
:tabclose:q | закрываем текущую вкладку | 
:tabclose i | закрываем i-ую вкладку | 
:tabonly | закрываем все вкладки кроме текущей | 
Reduce & Expand
| Command | Decsription | 
zc  | свернуть блок | 
| zo | развернуть блок | 
| zM | свернуть все блоки | 
| zR | развернуть все блоки | 
| za | инвертировать свернутые блоки | 
Macros
| Command | Decsription | 
qa  | Старт записи макроса a. | 
| q | остановка записи макроса. | 
| @a | Вызов макроса a | 
| n@a | исполнение макроса n-раз | 
Marks
| Command | Decsription | 
ma  | Установка метки a. | 
| 'a | переход на метку a | 
| d'a | удалить всё до метки a | 
:marks | Отображение меток | 
:delm! | Удаление всех меток в нижнем регистре | 
Commentary
commentary.vim - плагин для комментариев
| Command | Description | 
| NORM | |
| gcc | комментирование строки | 
| Ngcc | Комментирование N строк | 
| gc} | Комментировать до конца параграфа | 
| gc{ | Комментировать до начала параграфа | 
| gcNk | Комментировать N строк вверх | 
:X,YCommentary | Коментирование строк X-Y | 
Surround
vim-surround - оборачивание текста в кавычки и скобки
| Command | Description | 
| Normal Mode | |
| ds' | Удаление одинарных кавычек | 
| ds" | Удаление двойных кавычек | 
| cs"' | Замена двойных кавычек на одинарные | 
| Visual Mode | |
| S' | оборачивание выделенного текста в одинарные кавычки | 
| S" | оборачивание выделенного текста в двойные кавычки | 
FZF
https://github.com/junegunn/fzf
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf ~/.fzf/install cd ~/.vim-config/.vim/bundle git clone https://github.com/junegunn/fzf
vimrc
" --- open zfz on Ctrl + P nnoremap <C-p> :<C-u>FZF<CR>
| Command | Decsription | 
Ctrl+p  | Включение режима zfz | 
| Ctrl+c | Отключение режима zfz | 
| Ctrl+j or Down | Выделение вниз | 
| Ctrl+k or Up | Выделение вверх | 
| Ctrl+x | Открыть выделенный файл с горизонтальным разделением | 
| Ctrl+v | Открыть выделенный файл с вертикальным разделением | 
| Ctrl+t | Открыть выделенный файл новой вкладке | 
Grep
| Command | Decsription | 
:vimgrep QUERY dir/** | Поиск строки QUERY в файлах директории dir/ | 
Quickfix
| Command | Decsription | 
:copen | Open the quickfix window | 
:ccl | Close window | 
:cw | Open it if there are "errors", close it otherwise (some people prefer this) | 
:cn | Go to the next error in the window | 
:cp | Go to previous | 
:cnf | Go to the first error in the next file | 
Bash
| Command | Decsription | 
:!cmd | Выполнить bash-команду cmd | 
:!motionCMD | Фильтрация строк, попадающих под motion,  bash-командой CMD. Например, !10Gsort - сортировка строк между текущей и 10й bash-командой sort | 
:! | Выполнить пустую команду (отобразить предыдущий вывод) | 
:.!cmd | Выполнение bash-команды cmd и вставка стандартного вывода в текущую строку. Пример: :.!date | 
Terminal
Команда :term включает терминал с горизонтальным разделением.
Переход между терминалом и редактором Ctrlw+w
В терминале переход в режим просмотра комбинацией Ctrlw+N
Выход из режима просмотра i или a
Misc
| Command | Decsription | 
| NORM | |
:set paste | Режим "вклейки". Текст вставляется "как есть", без автоотсутпов | 
:set nopaste | Отключение режима "вклейки" | 
:set autowrite | Автоматическая запись при переходе к другому файлу. | 
| INSERT | |
C-R " | Вставить текст, скопированный yank | 
ccl | Скрыть список быстрых исправлений | 
C-K AB | Вставка символа из таблицы символов, AB комбинация из таблицы :digraphs | 
:retab | Изменить режим отступов в соответствии с текущими настройками | 
Трансляция кириллицы в латиницу. Позволяет выполнять команды в кириллической раскладке.
https://github.com/powerman/vim-plugin-ruscmd
# переключение курсора между буферами (,l) let mapleader = "," nmap <Leader>l <C-w>w
# переключение курсора между буферами (,l) let mapleader = "," nmap <Leader>l <C-w>w
Python
https://skillbox.ru/media/code/prevrashchaem-vim-v-polnotsennuyu-ide-dlya-python/
Rails
https://robots.thoughtbot.com/extending-rails-vim-with-custom-commands
| Command | Description | 
gf  | Перейти к файл под курсором | 
| Ctrl+wgf | Открыть файл под курсором в новой вкладке | 
| Ctrl+wf | Открыть файл под курсором с горизонтальным разделением | 
| Ctrl+wvgf | Открыть файл под курсором с вертикальным разделением | 
:A | Alternate. Переключение между MVC и MVC spec | 
:R | Related. Переключение связанных сущностей: экшн контроллера - вьюха, | 
:{E/S/V/T}controller | перейти к контроллеру | 
:{E/S/V/T}helper | перейти к хелперу | 
:{E/S/V/T}init | переход в routes.rb | 
:{E/S/V/T}mailel | перейти к майлеру | 
:{E/S/V/T}migration | перейти к миграции | 
:{E/S/V/T}schema | перейти к файлу схему | 
:{E/S/V/T}task | перейти к задаче | 
:{E/S/V/T}layout | перейти к корневому представлению | 
E - в текущей вкладке :editS - :splitV - :vsplitT - :tabedit | |
:Rails console | запуск Rails console | 
:Generate controller Blog | Запуск генератора | 
:help Rails | Справка по плагину | 
https://www.sitepoint.com/effective-rails-development-vim/
https://github.com/smolnar/vim-rails-bundle
https://robots.thoughtbot.com/intro-rails-vim
https://masteruby.github.io/productivity-booster/2014/05/02/vim-plugins-for-ruby.html#.WnCE03omzCI
Golang
vim-go | - полезные команды
git clone https://github.com/fatih/vim-go.git ~/.vim/bundle/vim-go
tagbar - панель со структурой файла
git clone git@github.com:majutsushi/tagbar.git ~/.vim/bundle/vim-tagbar
Добавляем строку в .vimrc
" ~/.vimrc nmap <F8> :TagbarToggle<CR>
Для корректной работы tagbar требуется ctags.
sudo apt-get install autoconf git clone git@github.com:universal-ctags/ctags.git cd ctags ./autogen.sh ./configure make sudo make install
vim-compiler-go - проверка синтаксиса
git clone https://github.com/rjohnsondev/vim-compiler-go.git ~/.vim/bundle/vim-compiler-go
В файл .vimrc необходимо прописать путь к директории установки Golang.
" ~/.vimrc let g:golang_goroot = "/usr/lib/go-1.10"
Узнать полный путь к этой директории можно командой
go env GOROOT
Snippets
https://github.com/SirVer/ultisnips
cd ~/.vim/bundle && git clone git://github.com/SirVer/ultisnips.git cd ~/.vim/bundle && git clone git://github.com/honza/vim-snippets.git
" ~/.vimrc " Trigger configuration. Do not use <tab> if you use https://github.com/Valloric/YouCompleteMe. let g:UltiSnipsExpandTrigger="<tab>" let g:UltiSnipsJumpForwardTrigger="<c-b>" let g:UltiSnipsJumpBackwardTrigger="<c-z>" " If you want :UltiSnipsEdit to split your window. let g:UltiSnipsEditSplit="vertical"
Открытие редактора снипетов :UltiSnipsEdit
Документация :help UltiSnips (или онлайн)
UltiSnips Screencast Episode 1
UltiSnips Screencast Episode 2
Ruby snippets (from procure gem)
global !p
def upperfirst(t):
    if len(t) < 2:
        return '' if len(t) < 1 else t.capitalize()
    return t[0].capitalize() + t[1:]
def lowerdash(t):
    return '-'.join([ w.lower() for w in re.findall('[a-z]+|[A-Z]+[a-z]*', t) ])
def snake(t):
    return '_'.join([ w.lower() for w in re.findall('[a-z]+|[A-Z]+[a-z]*', t) ])
endglobal
snippet llc "one line class"
class $1; end
endsnippet
snippet xc "class with include XML::Mapping"
class ${1}
  include XML::Mapping$0
end
endsnippet
snippet tn "text_node"
text_node :$2`!p snip.rv=snake(t[1])`, '$1'
endsnippet
snippet tno "text_node optional"
text_node :$2`!p snip.rv=snake(t[1])`, '$1', optional: true
endsnippet
snippet opt "optional: true" i
, optional: true
endsnippet
snippet on "object_node"
object_node :$2`!p snip.rv=snake(t[1])`, '$1',
            class: ${3:`!p snip.rv=upperfirst(t[1])`}
endsnippet
# --- EXAMPLES
snippet rc "require package that converts from camelCase or PascalCase to kebab-cased" b
const $1 = require('$2`!p snip.rv=lowerdash(t[1])`');
endsnippet
snippet imp "import package that converts from camelCase or PascalCase to kebab-cased" b
import $1 from '$2`!p snip.rv=lowerdash(t[1])`';
endsnippet
yaml.snippets
# --- TYPES snippet ta "type array" description: $1 type: array items: $2 endsnippet snippet to "type object" description: $1 type: object properties: $2 endsnippet snippet ti "type integer" description: $1 type: integer nullable: ${2:false} example: ${3:0} $0 endsnippet snippet tf "type float" description: $1 type: number format: float nullable: false example: ${2:1.23} $0 endsnippet snippet ts "type string" description: $1 type: string nullable: ${2:false} example: "${3:string}" $0 endsnippet snippet tbs "type binary string" description: $1 type: string format: binary nullable: ${2:false} $3 endsnippet snippet tdt "type date-time" description: $1 type: string format: date-time nullable: ${2:false} $0 endsnippet snippet turl "type url" description: $1 type: string format: uri nullable: ${2:false} example: "${3:http://example.com}" $0 endsnippet snippet tb "type boolean" description: $1 type: boolean default: ${2:false} nullable: ${3:false} $0 endsnippet # --- QUERY PARAMETERS snippet parip "parameter integer in path" - name: $1 in: path description: $2 required: true schema: type: integer endsnippet snippet pars "parameter string in query" - name: $1 in: query description: $2 required: ${3:false} schema: type: string endsnippet snippet parsort "parameter for sorting" - name: sort_by in: query description: Сортировка записей по заданному полю required: false schema: type: string enum: [$1] $0 endsnippet snippet parpages "parameter with referenced page and limit" - $ref: "${1:../../swagger.yaml}#/components/parameters/page" - $ref: "$1#/components/parameters/limit" endsnippet snippet parif "parameter with referenced Id-Modified-Since" - $ref: "${1:../../swagger.yaml}#/components/parameters/ifmods" endsnippet snippet parauth "parameter with referenced Authorization" - $ref: "#/components/parameters/auth" endsnippet # --- REFERENCES snippet refc "reference to component" $ref: "${1:../../swagger.yaml}#/components/schemas/$2" endsnippet # --- PATHS snippet pathget "path get" ${1:get}: summary: $2 operationId: `!v expand('%:t:r')` tags: - $3 parameters: responses: "200": description: Успешный запрос content: application/json: schema: "401": $ref: "${4:../../swagger.yaml}#/components/responses/Unauthorized" endsnippet snippet pathpost "path post" post: summary: $1 operationId: ${2:`!v expand('%:t:r')`} tags: - $3 requestBody: required: true content: application/json: schema: type: object properties: $0 responses: "200": description: Успешный запрос content: application/json: schema: "401": $ref: "${4:../../swagger.yaml}#/components/responses/Unauthorized" "422": $ref: "$4#/components/responses/UnprocessableEntity" endsnippet # --- RESPONSES snippet 304 "NotModified response" "404": $ref: "${1:../../swagger.yaml}#/components/responses/NotModified" endsnippet snippet 404 "NotFound response" "404": $ref: "${1:../../swagger.yaml}#/components/responses/NotFound" endsnippet snippet 422 "UnprocessableEntity response" "422": $ref: "${1:../../swagger.yaml}#/components/responses/UnprocessableEntity" endsnippet # --- HEADERS snippet hlast "header Last-Modified" Last-Modified: $ref: "${1:../../swagger.yaml}#/components/headers/Last-Modified" $0 endsnippet snippet hpages "header paginate" X-Total: $ref: "${1:../../swagger.yaml}#/components/headers/X-Total" X-Page: $ref: "$1#/components/headers/X-Page" X-TotalPages: $ref: "$1#/components/headers/X-TotalPages" $0 endsnippet
Syntax highlighting & Themes
http://vimcolors.com/
| Команда | Описание | 
:syntax on | включение подсветки синтаксиса | 
:syntax off | отключение подсветки | 
Rails Theme
https://github.com/jpo/vim-railscasts-theme
JS Hightlite
https://github.com/jelera/vim-javascript-syntax
Markdown Highlight
" --- отсключение folding по умолчанию let g:vim_markdown_folding_disabled = 1
Изменение цвета курсора
https://stackoverflow.com/questions/34251566/how-can-i-change-the-cursor-style-in-vim-depending-if-im-in-insert-mode-or-norm
Plugins
Pathogen
Pathogen - плагин для управления плагинами
# устанавливаем плагин mkdir -p ~/.vim/autoload ~/.vim/bundle && \ curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim # корректируем файл конфигурации vim vim ~/.vimrc
Добавляем строки
execute pathogen#infect() syntax on filetype plugin indent on
Плагины, помещенные в директорию ~/.vim/bundle будут активироваться автоматически.
Пример загрузки плагина vim-sensible
cd ~/.vim/bundle && \ git clone https://github.com/tpope/vim-sensible.git
Troubleshooting
Не работает цветовая схема в tmux
Решение https://stackoverflow.com/questions/10158508/lose-vim-colorscheme-in-tmux-mode
Создаем или редактируем файл конфигурации tmux
# ~/.tmux.conf set -g default-terminal "xterm-256color"
Ошибки при старте vim-config на новом сервере
vim . ... line 28: E474: Invalid argument: listchars=tab:>·,trail:~,extends:>,precedes:<,space:.
Возможно установлена некорректная локаль в ОС. Открываем файл ~/.vim-config/vimrc и кириллица будет нарушена.
Решение:
# --- текущая локаль locale # --- доступные локали locale -a # --- генерация новой (если нет ru_RU.UTF-8) sudo locale-gen ru_RU.UTF-8 # --- устанавливаем текущую sudo update-locale LANG=ru_RU.UTF-8
Error detected while processing .vimrc:
Чаще всего на новом сервере при первом запуске vim видим нечто подобное:
Error detected while processing /home/zoid/.vimrc: line 22: E474: Invalid argument: listchars=tab:>·,trail:~,extends:>,precedes:<,space:. Press ENTER or type command to continue
При этом в открытом файле наблюдаем нарушение отображения некоторых символов.
Этом может быть связано с тем, что на сервере не установлена русская локаль:
sudo locale LANG=en_US ... sudo locale -a | grep ru # ничего не выводится
Решение: https://vps.ua/wiki/setting-russian-locale-linux/
sudo apt-get install language-pack-ru sudo vim /etc/default/locale # заменяем содержимое на LANGUAGE=ru_RU:ru LANG=ru_RU.UTF-8
Буфер обмена
Ubuntu
По-умолчанию vim не поддерживает работу с системным буфером обмена. Для работы с ним необходимо установить vim-gnome вместо vim.
# проверяем поддержку # -xterm_clipboard - не поддерживается # +xterm_clipboard - поддерживается vim --version | grep .xterm_clipboard -o # удаляем "старый" vim sudo apt-get purge vim sudo apt-get autoremove # устанавливаем "новый" sudo apt-get install vim-gtk3
Комбинации клавиш
"+y - копирование в буфер
"+d - вырезание в буфер
"+p - вставка из буфера
WSL
https://www.reddit.com/r/bashonubuntuonwindows/comments/be2q3l/how_do_i_copy_whole_text_from_vim_to_clipboard_at/el2vx7u/?utm_source=share&utm_medium=web2x
" WSL yank support
let s:clip = '/mnt/c/Windows/System32/clip.exe'  " change this path according to your mount point
if executable(s:clip)
    augroup WSLYank
        autocmd!
        autocmd TextYankPost * if v:event.operator ==# 'y' | call system(s:clip, @0) | endif
    augroup END
endif
"Зависание" vim
В произвольный момент vim "зависает" - перестает отвечать на команды. Причиной тому может служить комбинация Ctrl+S
Лечение - Ctrl-Q
