Рефакторинг у Vim


99

Звичайно, той факт, що ви можете рефакторувати IDE, для багатьох безцінний, я навряд чи коли-небудь роблю це, коли кодую, але я можу спробувати це зробити, редагуючи чуже джерело. Як ви виконуєте таке тривіальне завдання для декількох файлів у Vim?

Я знайшов цей плагін для рефакторингу Ruby, але як щодо "будь-якої" мови?


2
Рефакторинг дуже мовний. Вам потрібно шукати конкретні доповнення для кожної мови, яка вас цікавить. Можливо, ви знайдете доповнення для одних, а не для інших. Якщо є один, якого ви хочете і не можете знайти, то, якщо ви відчуваєте амбіцію, ви можете спробувати написати його, використовуючи існуючий надбудову для іншої подібної мови як вихідну точку.
Стів Йоргенсен

2
VIM призначений для редагування окремих файлів і, можливо, файлів у каталозі, а не проектів . Багато рефакторингів, що підтримуються IDE, впливатимуть на файли у всьому проекті (наприклад, перейменування класу). Думаю, було б складно отримати це "право" за допомогою редактора типу (g) VI (m), до того моменту, коли, на мою думку, компанії чи великому проекту довелося б взяти його на себе. Їм в основному доведеться проаналізувати кожну мову, щоб уникнути простих підстановок рядків і стати схильним до помилок (ctags дає щось з цього), а також відповідних типів проектів (щоб знати, які файли редагувати).
Merlyn Morgan-Graham

1
Дякую за коментарі, я думаю, що тут все починає ставати хитромудрим, і спроба прив'язати VIM до IDE не є таким елегантним рішенням використання лише однієї програми для редагування декількох мов. Я справді не хочу відмовлятися від VIM через деякі "розширені" функції, доступні в IDE.
Helmut Granda

@ MerlynMorgan-Graham - Деякі люди просто зберігають свій код у декількох (таких, що можуть бути) файлах. Взагалі уникає цієї проблеми.
Ладья

7
@ldigas: Це могло б обійти проблему. Але це суперечить рекомендованим практикам для деяких мов (наприклад, Java). В основному код згинається відповідно до потреб інструменту, коли насправді має бути навпаки.
Merlyn Morgan-Graham

Відповіді:


78

Я погоджуюсь з парадигмою "Vim - це не IDE". Але бувають випадки, коли IDE відсутній. Ось що я використовую в таких ситуаціях:

: grep,: vimgrep,: Ag,: Ggrep

Рефакторинг, який більше пов’язаний із регулярними замінами, я зазвичай використовую : grep у своєму дереві проектів, а потім записую макрос для виконання рефактора - - g та: s не є головними умовами. Зазвичай це дозволяє мені швидко модифікувати велику кількість файлів з дуже невеликими зусиллями. Чесно кажучи, я використовую цей метод більше, ніж будь-який інший.

Залежно від робочого процесу, вбудовані команди можуть бути повільними / незручними. Якщо ви використовуєте git, то ви хочете використовувати чудовий плагін Fugitive та його :Ggrepкоманду лише для пошуку файлів, зареєстрованих у git. Мені також подобається Silver Searcher за його швидкість.

: argdo,: cdo та: bufdo

: cdo та : argdo зручні для виконання команд vim над набором файлів.

командний рядок

Коли важче визначити список файлів, які потребують змін, :vimgrepя вдаюся до командного рядка grep / find команд, щоб більш пильно курирувати список файлів, які мені потрібні для рефакторингу. Збережіть список у текстовому файлі та використовуйте :eта змішайте записи макросів, щоб внести зміни, які мені потрібно внести.

Я вважаю, що чим менше іржавим я зберігаю свої навички макрозапису, тим кориснішим вважаю Vim для рефакторингу: відчуваю себе комфортно зберігати / відновлювати з реєстрів, збільшувати / зменшувати змінні лічильника реєстру, чистити / зберігати записи макросів у файл для подальшого використання тощо.


Оновлення

З моменту написання цього на vimcasts.org було опубліковано більше відеозаписів для описаних мною методів (я закликаю вас переглянути ВСІ Vimcasts! ). Для рефакторингу слідкуйте за цими:

Вимгольф - також чудовий спосіб тренуватися.

Повсюдність серверів протоколів Language Server, оскільки я написав цю відповідь, також принесла деяку можливість рефакторингу Vim (та іншим редакторам). ІМО вони далекі від рівних можливостей рефакторингу, які ви бачили б у спеціально створеній IDE (я їх використовую, і віддаю перевагу кокам та ALE). Подивіться інші відповіді на це питання, щоб отримати додаткову інформацію!


12
Рефакторинг - це НАБІЛЬШЕ, ніж зіставлення зразків, ось чому IDE потрібні для безпечної автоматизації цього. Очевидно, що ви можете зробити це вручну, але, враховуючи доступні варіанти, і що більшість випадків безпечніше робити це вручну, чому б ви взагалі розглядали будь-який інший варіант?
Кутберто Окампо,

1
@CutbertoOcampo Я певною мірою з вами погоджуюсь: залежно від безлічі аспектів проекту (структура, мова (мови), навички та ресурси персоналу, щоб назвати декілька), МОЖЕ бути чудовим інструментом рефакторингу, застосовним до вашої проблеми. Моя відповідь стосується ситуацій, коли це не відповідає дійсності, і ви хочете вирішити проблему у Vim.
dsummersl

2
це добре, я розумію, що людям може бути зручніше робити щось, використовуючи свої давно віддані перевагу інструментам, і що є кілька хакерів, які можуть працювати дуже добре, напевно, краще, ніж будь-яка IDE, але для інших -box рішення Я б сказав, що реальна IDE буде працювати ефективніше для більшості користувачів. Я б міркував над ситуацією на 80-20% (навіть більше, з залишком на користь IDE).
Кутберто Окампо,

1
Практично для кожної мови існує ідея. Спроба рефакторингу за допомогою vim або регулярного виразу звучить абсолютно божевільно. Чому б ти навіть намагався?
котиться

1
@rolls, щоб бути достатньо потужним, щоб схопити машину, що потребує випадкового колеги, з не-вашим ідеєм або будь-яким іншим CFG, з яким ви можете жити, і залишити гарне враження навколо (не для "просто враження", а для репутації та майбутньої позиції).
кривавий

24

Протокол мовного сервера (LSP)

Протокол мовного сервера містить функцію для розумного перейменування символів у проекті:

https://microsoft.github.io//language-server-protocol/specifications/specification-3-14/#textDocument_rename

Наприклад, наступний мовний сервер підтримує це:

Ви можете знайти більше мовних серверів за адресою https://langserver.org/ .

Vim

Клієнт редактора vim необхідний, щоб використовувати їх у межах vim. Існують такі варіанти:

  1. LanguageClient-neovim (вимагає іржі) пропонує відображення:

    nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
    
  2. coc.nvim (вимагає node.js) пропонує відображення:

    " Remap for rename current word
    nmap <leader>rn <Plug>(coc-rename)
    
  3. Ель має

    nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
    

    Ale не визначає жодних прив'язок клавіш. Це повинен зробити користувач.

  4. vim-lsp забезпечує наступну команду

    :LspRename
    

    Подібно до Еля, не пропонується картографування. Однак, звичайно, ви можете визначити такий як наступний

    nmap <leader>r <plug>(lsp-rename)
    

    ( <leader>rмає бути замінено вашим вибором; я не знаю того, з яким погоджується більшість плагінів)

  5. vim-lsc має відображення за замовчуванням:

    'Rename': 'gR'
    

Див. Також YouCompleteMe, який також сприяє LSP.

Неовім

Neovim має початкову вбудовану підтримку lsp з 13.11.2019

Див. Загальні конфігурації LSP https://github.com/neovim/nvim-lsp

Однак я не міг зрозуміти, як працює розумне перейменування. Якщо хтось це знає, оновіть цей розділ.

Інші рефакторинг

Я не знаю, чи планується протокол LSP підтримувати більш складні рефакторингу, такі як зміна структури класу, додавання параметрів до методів / функцій або переміщення методу до іншого класу. Список рефакторингу див. На https://refactoring.com/catalog/ .


На жаль, підтримка рефакторингу в LSP в даний час є досить слабкою порівняно із станом техніки. github.com/Microsoft/language-server-protocol/issues/61
Мікаель

AFAIK, що перейменування coc-renameпрацює лише на поточному буфері. Це не оновило використання експортованого імені в усьому світі в проекті (між файлами).
олігофрен,

15

Python

Для мови python наступні плагіни надають `` розумні '' можливості перейменування для vim:

  • jedi-vim( github )<leader>r
  • ropevim( github )CTRL-c r r
  • python-mode( github ):h pymode-rope-refactoring

13

Сімейство С

  1. Спробуйте плагін Clighter для перейменування рефакторингу для сімейства c. Він заснований на clang, але є обмеження, і плагін позначено як застарілий.

    Запропоноване відображення Clighter - це

     nmap <silent> <Leader>r :call clighter#Rename()<CR>
    

    Зверніть увагу, наступний плагін clighter8 видалив функцію перейменування у коміті 24927db42 .

  2. Якщо ви використовуєте неовім, ви можете поглянути на затискач плагіна . Це підказує

     nmap <silent> <Leader>r :call ClampRename()<CR>
    

5

Я написав цей плагін для загального рефакторингу. Це все ще вимагає багатьох удосконалень. Десь у майбутньому я спробую відмовитися від ctags на користь clang для рефакторингу C & C ++.


4

Можливо, не найелегантніше рішення, але я знайшов його дуже зручним: я використовую ECLIM для підключення VIM та Eclipse. Звичайно, все моє редагування вихідного коду виконується у VIM, але коли настає час рефакторингу, можна скористатися чудовими можливостями Eclipse у цьому питанні.

Спробувати.


3

Фактор плагіна

Існує ще один плагін vim, призначений для рефакторингу, який називається faktor, який доступний на github .

В даний час (2017-12) він підтримує мови

  • c,
  • java та
  • пітон.

3

Плагін YouCompleteMe ( YCM ) (20 тис. Зірок на Github )

http://ycm-core.github.io/YouCompleteMe/#the-refactorrename-new-name-subcommand

:h RefactorRename-new-name

У підтримуваних типах файлів ця команда намагається виконати семантичне перейменування ідентифікатора під курсором. Сюди входить перейменування декларацій, визначень та використання ідентифікатора або будь-яка інша відповідна мові дія. Конкретна поведінка визначається використовуваним семантичним рушієм.

Схожий на FixIt , ця команда застосовує автоматичні зміни до вихідних файлів. Операції перейменування можуть включати зміни в декількох файлах, які можуть бути відкритими або не бути відкритими в буферах Vim. YouCompleteMe обробляє все це за вас. Поведінка описана в наступному розділі.

Підтримується у типах файлів: c, cpp, objc, objcpp, cuda, java, javascript, машинопис, rust, cs

За замовчуванням відображення відсутнє.


Тож наразі це працює лише для javascript, typecript та java?
SR

2

Помістіть курсор на ім'я для рефактору та типу

gd (або gD якщо ви переробляєте глобальну змінну).

Тоді

cgn нове_ім'я esc

і

. один або кілька разів для рефакторингу наступних випадків

або

:%norm . для рефакторингу всіх випадків в буфері одночасно.


1

Я пишу багато коду C / C ++ у vim. Найбільш поширеним рефакторингом, який я роблю, є перейменування змінних, назв класів і т. Д. Зазвичай я використовую :bufdo :%s/source/dest/gдля пошуку / заміни у файлах, що майже те саме, що і перейменування, яке надається великими середовищами IDE.
Однак у своєму випадку я виявив, що зазвичай перейменовую подібні сутності, написані в різних регістрах (наприклад, CamelCase, snake_case тощо), тому я вирішив написати невеличку утиліту, яка допоможе у пошуку "розумного випадку" / замінити, він розміщений тут . Це утиліта командного рядка, а не плагін для vim, я сподіваюся, що ви можете виявити це корисним.


0

Для рефакторингу, якщо ви використовуєте Unite (а вам слід), ви можете використовувати vim-qfreplace і зробити це надзвичайно простим. Перевірте це відео, яке демонструє, як це працює. Як тільки ваш робочий процес встановлений, ви можете зробити деякі зіставлення, щоб оптимізувати його (замість того, щоб вводити більшість речей, як у відео).


0

Поєднання двох плагінів: ВІМ-ripgrep , знайти в файлах і помістити результати в вікні QuickFix і QuickFix-рефлектор , щоб зберегти зміни прямо в вікні QuickFix і мати його автоматично зберегти кожну зміну через файли.


0

Я б подумав про використання версії emacs для spacemacs. Він використовує ті самі режими та більшість натискань клавіш, що і Vim, але має набагато більше доповнень, оскільки це шепелявий характер. Якщо ви хочете програмувати на C ++, ви просто додаєте рівень c ++, і більша частина IDE вже налаштована для вас. Для інших інтерпретованих мов, таких як python або bash, вам не потрібно залишати пробіли, щоб використовувати їх. У них навіть є спосіб запускати блоки коду безпосередньо у вашому тексті, що чудово працює для грамотного програмування або відтворюваного програмування, де код і дані знаходяться в одному файлі. Обидва зроблені як текст.

Spacemacs набагато важче передає початкове навантаження, але додаткові речі, які ви можете з ним робити, коштують декількох секунд вартості запуску. Одношаровий організаційний режим варто перевірити. Це найкращий контур, програміст, денний таймер / список завдань, я коли-небудь використовував.


0

Іди

  1. Інструмент godoctor ( github ) підтримує кілька можливостей рефакторингу
  • Перейменувати
  • Функція вилучення
  • Витяг локальної змінної
  • Перемкнути var var: =
  • Додайте заглушки Годока

Існує плагін vim https://github.com/godoctor/godoctor.vim, який робить їх доступними

З курсором у речі, щоб перейменувати:

:Rename <newname>

Блок виділення для вилучення:

:Refactor extract newfunc
  1. вим-го

    • Точне безпечне перейменування ідентифікаторів за допомогою :GoRename.
  2. Мовний сервер gopls

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.