Изменение имен переменных в Vim
Я пытаюсь прочитать много кода c/perl через vim, который содержит много имен переменных одной буквы.
Было бы неплохо иметь некоторую команду, которая могла бы помочь мне изменить имя переменной на что-то более значимое, пока я нахожусь в процессе чтения кода, чтобы я мог быстрее прочитать остальную часть.
Есть ли какая-то команда в vim, которая позволила бы мне быстро это сделать.
Я не думаю, что регулярные выражения будут работать cos
1) одно и то же однобуквенное имя может иметь разные цели в разных областях видимости -
2) одна и та же комбинация букв может быть частью другого более крупного имени var, или в строке или комментарии.. не хотели бы изменять эти
Любые известные решения
Ответы
Ответ 1
Ниже описано, как переименовать переменную, которая определена в текущей области {}
.
Переместите курсор на использование переменной. Нажмите gd
. Это означает - переместите курсор в определение.
Теперь нажмите [{
- это приведет вас к началу области.
Нажмите V
- включите выбор Visual Line.
Нажмите %
- перейдем к противоположному }
, таким образом, выберем всю область.
Нажмите :s/
- начните замену команды.
<C-R>/
- вставляет шаблон, соответствующий имени переменной (это имя было нажато до нажатия gd
).
/newname/gc<CR>
- инициирует поиск и замену с подтверждением в каждом матче.
Теперь вам нужно записать макросы или даже лучше - нанести на карту ключ.
Вот окончательные сопоставления:
" For local replace
nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>
" For global replace
nnoremap gR gD:%s/<C-R>///gc<left><left><left>
Поместите это в свой .vimrc
или просто выполните.
После этого нажатие gr
на локальной переменной приведет вас к команде :s
, где вы просто должны ввести new_variable_name
и нажать Enter.
Ответ 2
AFAIK, фактическая поддержка рефакторинга в VIM отсутствует. При переименовании с целью рефакторинга я обычно принимаю следующие меры предосторожности.
- Ограничьте область изменения моего использования меток.
- При вводе регулярного выражения скопируйте имя с помощью \< и > . Это приведет к совпадению целого слова, которое уменьшит типы неправильных переименований, которые произойдут.
- Не выполняйте многострочную замену, чтобы уменьшить вероятность плохой замены.
- Внимательно просмотрите код diff, если это не что иное, как небольшое изменение.
Мое конечное изменение выглядит примерно так:
:'a,'bs/\<foo\>/bar
Я хотел бы ошибаться в том, что не существует инструмента для рефакторинга для VIM, но я его не видел.
Ответ 3
Поместите это в свой .vimrc
" Function to rename the variable under the cursor
function! Rnvar()
let word_to_replace = expand("<cword>")
let replacement = input("new name: ")
execute '%s/\(\W\)' . word_to_replace . '\(\W\)/\1' . replacement . '\2/gc'
endfunction
Назовите его :call Rnvar()
expand("<cword>")
получает слово под курсором. Строка поиска использует %
для области видимости файла, а шаблоны \(\W\)
ищут символы без слов на границе слова для замены и сохраняют их в переменных \1
и \2
, чтобы быть повторно - вставляется в шаблон замены.
Ответ 4
Вы можете использовать модификатор 'c' в глобальном поиске и заменить его, чтобы попросить вас подтвердить каждую замену. Это займет больше времени, но это может работать для файла с огромным кодом:
%s/\$var/\$foo/gc
С означает подтверждение.
Ответ 5
В c, вы можете сделать некоторый прогресс, используя cscope. Он пытается понять синтаксис, поэтому у него будет возможность узнать, когда буква была переменной.
Ответ 6
Если это относится к нескольким файлам, вы можете рассмотреть возможность поиска sed. Используйте find, чтобы захватить ваши файлы и xargs plus sed для замены. Предположим, вы хотите заменить a на имя a_better_имя во всех файлах, соответствующих *.c, вы могли бы сделать
найти. -name "*.c" | xargs sed -i -e 's/a/a_better_name/g'
Имейте в виду, что это заменит ВСЕ вхождения a, поэтому вам может понадобиться более надежное регулярное выражение.