Добавить в корзинуПозвонить
Найти в Дзене
Vim

VimScript 35 [ оператор grep часть 3]

| ч34. оператор grep часть 2 | Содержание | ч36. списки | Наш новый "оператор grep" отлично работает, но мы не были внимательны к нуждам наших пользователей. Нам надо сделать еще пару вещей, чтобы наш оператор хорошо работал в экосистеме Vim. Сохранить регистр Копируя текст в "безымянный регистр", мы удаляем все, что было там ранее. Кроме того, используя визуальное выделение для копирования текста, мы также уничтожаем любую запись самого последнего визуального выделения, так же у нас происходит удаление пользовательского выделения когда мы работаем посимвольно (<leader> giw) Такое поведение нашего кода будет очень не удобным, поэтому давайте не будем использовать визуальный выбор при посимвольной работе, а также сохраним содержимое безымянного регистра, чтобы мы могли восстановить его после завершения работы нашего скрипта. Измените код, чтобы он выглядел следующим образом: nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call GrepOperator(visualmode())
Оглавление

| ч34. оператор grep часть 2 | Содержание | ч36. списки |

Наш новый "оператор grep" отлично работает, но мы не были внимательны к нуждам наших пользователей. Нам надо сделать еще пару вещей, чтобы наш оператор хорошо работал в экосистеме Vim.

Сохранить регистр

Копируя текст в "безымянный регистр", мы удаляем все, что было там ранее. Кроме того, используя визуальное выделение для копирования текста, мы также уничтожаем любую запись самого последнего визуального выделения, так же у нас происходит удаление пользовательского выделения когда мы работаем посимвольно (<leader> giw)

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

nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr>

function! GrepOperator(type)
let saved_unnamed_register = @@

if a:type ==# 'v'
normal! `<v`>y
elseif a:type ==# 'char'
normal! `[y`]
else
return
endif

silent execute "grep! -R " . shellescape(@@) . " ."
copen

let @@ = saved_unnamed_register
endfunction

Мы добавили два [ let ] оператора в верхней и нижней части функции. Первый сохраняет содержимое [ @@ ] в переменную, а второй восстанавливает его. Кроме того, мы применили копирование с движением, а не с визуальным выделением.

Сохраните и запустите исходный код. [ :w | source % ]. Убедитесь, что он работает, выделив некоторый текст, затем нажав [<leader>giw ], чтобы запустить наш оператор, затем нажмите [ p ], чтобы вставить текст, который вы выделяли ранее.

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

Пространство имен

Наш скрипт создал функцию с именем GrepOperator в глобальном пространстве имен. Вероятно, это не имеет большого значения, но когда вы пишете Vimscript, гораздо лучше перестраховаться, чем потом сожалеть.

Мы можем избежать загрязнения глобального пространства имен, изменив пару строк в нашем коде. Отредактируйте файл, чтобы он выглядел следующим образом

nnoremap <leader>g :set operatorfunc=<SID>GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call <SID>GrepOperator(visualmode())<cr>

function! s:GrepOperator(type)
let saved_unnamed_register = @@

if a:type ==# 'v'
normal! `<v`>y
elseif a:type ==# 'char'
normal! `[v`]y
else
return
endif

silent execute "grep! -R " . shellescape(@@) . " ."
copen

let @@ = saved_unnamed_register
endfunction

Первые три строки скрипта изменились. Сначала мы изменили имя функции, чтобы оно начиналось с [ s: ], это помещает его в пространство имен текущего скрипта.

Мы также изменили сопоставление и GrepOperator дополнили их имя функции знаком <SID>, чтобы они могли найти функцию. Если бы мы этого не сделали, они попытались бы найти функцию в глобальном пространстве имен, что не сработало бы.

Поздравляю, мы создали наш первый скрипт: grep-operator.vim

Ура! Надо это дело отметить!

Упражнения

Прочитайте :help <SID>

| ч34. оператор grep часть 2 | Содержание | ч36. списки |