Vim: изменить сигнатуру вызова функции через базу кода
Я медленно превращаю Vim в свою IDE по выбору, с помощью ctags и плагинов static-analysis/autocompletion/etc (например, vim-jedi, youcompleteme и т. Д.). Но я не нашел ничего, что могло бы выполнить одну конкретную задачу:
Скажем, у меня есть функция (я буду использовать Python здесь):
def my_function(outFile, foo, bar):
outFile.write(foo[bar])
Позже я изменяю его подпись, чтобы позиционный аргумент outFile был именованным:
def my_function(foo, bar, outFile=None):
if outFile is None:
outFile = getDefaultOutfile()
outFile.write(foo[bar])
Теперь я хочу изменить все старые вызовы, несмотря на всю кодовую базу:
my_function(oF, f, b)
в
my_function(f, b, outFile=oF)
Есть ли простой способ сделать это в Vim (или других утилитах Linux, например, sed)? Я знаю, что PyCharm и т.д. могут это сделать, но я пока не собираюсь прыгать с корабля.
2 ответа
Вы можете сделать это следующим образом:
:s/\vmy_function\((\w*), (\w*), (\w*)\)/my_function(\2, \3, outfile=\1)/g
Читайте о vimregex, особенно о захвате групп. В основном, что угодно (\w*)
совпадения будут сохранены и названы \1
(затем \2
, \3
и т. д.) для использования в замен позже.
Стоит отметить, что это работает для вашего примера, но не будет работать, если есть лишние или недостающие пробелы. Чтобы сделать это более надежным, вы можете изменить его на:
:s/\vmy_function\((\w*),\s*(\w*),\s*(\w*)\)/my_function(\2, \3, outfile=\1)/g
В качестве альтернативы find
(описано в предыдущем комментарии), можно также использовать grep
чтобы открыть файлы, содержащие нужную функцию:
vim `grep -l 'my_function' *py`
Файлы будут загружены в разные буферы. Затем используйте общую замену буфера:
bufdo %s/\(my_function\)(.*)/\1(f, b, outFile=oF)/gc
c
Флаг здесь не является обязательным, но я бы рекомендовал для этой конкретной замены.