Refactoring di Vim

100

Tentu saja fakta bahwa Anda dapat melakukan refaktor pada IDE tidak ternilai harganya bagi banyak orang, saya hampir tidak pernah melakukannya ketika saya membuat kode tetapi saya mungkin mencoba melakukannya saat mengedit sumber orang lain. Bagaimana Anda menyelesaikan tugas sepele seperti itu di banyak file di Vim?

Saya menemukan plugin ini untuk refactoring Ruby, tapi bagaimana dengan bahasa "apa saja"?

Helmut Granda
sumber
2
Refactoring sangat spesifik terhadap bahasa. Anda perlu mencari add-on khusus untuk setiap bahasa yang Anda minati. Anda mungkin akan menemukan add-on untuk beberapa dan bukan untuk yang lain. Jika ada yang Anda inginkan dan tidak dapat ditemukan, maka jika Anda merasa ambisius, Anda dapat mencoba menulisnya, menggunakan add-on yang ada untuk bahasa lain yang serupa sebagai titik awal.
Steve Jorgensen
2
VIM dirancang untuk mengedit file tunggal, dan mungkin file di bawah direktori - bukan proyek . Banyak pemfaktoran ulang yang didukung IDE akan memengaruhi file di seluruh proyek (misalnya, mengganti nama kelas). Saya pikir akan sulit untuk mendapatkan "hak" ini dengan editor seperti (g) VI (m), ke titik di mana saya pikir sebuah perusahaan atau proyek besar harus melakukannya. Mereka pada dasarnya harus mengurai setiap bahasa untuk menghindari melakukan substitusi string sederhana dan menjadi rentan terhadap kesalahan (ctag memberikan beberapa di antaranya ), serta jenis proyek yang sesuai (untuk mengetahui file mana yang akan diedit).
Merlyn Morgan-Graham
1
Terima kasih atas komentarnya, saya pikir di sinilah hal-hal mulai menjadi rumit dan mencoba membengkokkan VIM ke IDE bukanlah solusi yang elegan untuk menggunakan hanya satu program untuk mengedit banyak bahasa. Saya benar-benar tidak ingin menyerah pada VIM karena beberapa fitur "lanjutan" tersedia di IDE.
Helmut Granda
@ MerlynMorgan-Graham - Beberapa orang hanya menyimpan kode mereka dalam beberapa (besar, mungkin) file. Hindari masalah ini sama sekali.
Benteng
7
@ldigas: Itu akan mengatasi masalah. Tapi itu sangat bertentangan dengan praktik yang direkomendasikan untuk beberapa bahasa (misalnya Java). Pada dasarnya pembengkokan kode agar sesuai dengan kebutuhan alat, padahal seharusnya sebaliknya.
Merlyn Morgan-Graham

Jawaban:

78

Saya setuju dengan paradigma 'Vim is not an IDE'. Tetapi ada kalanya tidak ada IDE. Inilah yang saya gunakan dalam situasi tersebut:

: grep,: vimgrep,: Ag,: Ggrep

Refactoring yang lebih berkaitan dengan penggantian biasa Saya biasanya menggunakan : grep pada pohon proyek saya dan kemudian merekam makro untuk melakukan refactor -: g dan: s tidak punya otak. Biasanya saya akan dengan cepat mengubah sejumlah besar file dengan sedikit usaha. Sejujurnya, saya menggunakan metode ini lebih dari yang lain.

Bergantung pada alur kerja Anda, perintah bawaan mungkin lambat / tidak nyaman. Jika Anda menggunakan git, Anda akan ingin menggunakan plugin Fugitive yang sangat baik dan :Ggrepperintahnya untuk hanya mencari file yang diperiksa di git. Saya juga menyukai Pencari Perak karena kecepatannya.

: argdo,: cdo, dan: bufdo

: cdo dan : argdo berguna untuk menjalankan perintah vim pada satu set file.

garis komando

Ketika lebih sulit untuk menentukan daftar file yang perlu diubah melalui :vimgrepsaya menggunakan baris perintah grep / find perintah untuk lebih dekat mengatur daftar file yang perlu saya refactor. Simpan daftar ke file teks dan gunakan :eserta gabungan rekaman makro untuk membuat perubahan yang perlu saya buat.

Saya menemukan bahwa semakin tidak berkarat saya menjaga keterampilan perekaman makro saya semakin berguna saya menemukan Vim untuk refactoring: merasa nyaman menyimpan / memulihkan dari register, menambah / mengurangi variabel penghitung register, membersihkan / menyimpan rekaman makro ke file untuk digunakan nanti, dll.


Memperbarui

Sejak menulis ini, lebih banyak videocast untuk metode yang saya jelaskan telah diterbitkan di vimcasts.org (Saya mendorong Anda untuk menonton SEMUA Vimcast! ). Untuk refactoring, jam tangan ini:

Vimgolf juga merupakan cara yang bagus untuk berlatih.

Keberadaan server Language Server Protocol sejak saya menulis jawaban ini juga membawa beberapa kemampuan refactoring ke Vim (dan editor lain). IMO mereka masih jauh dari kemampuan menyamakan kemampuan refactoring yang akan Anda lihat dalam IDE yang dibuat khusus (saya menggunakannya, dan lebih suka coc dan ALE). Lihat jawaban lain untuk pertanyaan ini untuk info lebih lanjut!

dsummersl.dll
sumber
12
Refactoring CARA lebih dari sekadar pencocokan pola, itulah mengapa IDE diperlukan untuk mengotomatiskan ini dengan cara yang aman. Jelas, Anda dapat melakukannya secara manual, tetapi mengingat opsi yang tersedia, dan bahwa sebagian besar waktu lebih aman untuk melakukannya secara manual, mengapa Anda bahkan mempertimbangkan opsi lain?
Cutberto Ocampo
1
@CutbertoOcampo Saya setuju dengan Anda sampai batas tertentu: bergantung pada banyak sekali aspek proyek (struktur, bahasa, keterampilan & sumber daya staf, untuk beberapa nama), MUNGKIN ada alat pemfaktoran ulang yang bagus yang dapat diterapkan untuk masalah Anda. Jawaban saya berlaku untuk situasi ketika itu tidak benar, dan Anda ingin mengatasi masalah di Vim.
dsummersl
2
tidak apa-apa, saya mengerti orang mungkin merasa lebih nyaman melakukan sesuatu menggunakan alat pilihan lama mereka, dan bahwa ada beberapa peretasan yang dapat bekerja dengan sangat baik, mungkin lebih baik daripada IDE mana pun di luar sana, tetapi untuk yang sudah lama -box solution Menurut saya, IDE yang sebenarnya akan bekerja lebih baik bagi sebagian besar pengguna. Saya akan memikirkan jenis situasi 80-20% (bahkan lebih, dengan keseimbangan yang mendukung IDE).
Cutberto Ocampo
1
Ada ide untuk hampir setiap bahasa. Mencoba melakukan refactoring dengan vim atau regex terdengar benar-benar gila. Mengapa Anda mencoba?
memutar
1
@rolls agar cukup kuat untuk mengambil mesin yang membutuhkan kolega acak dengan bukan-ide-Anda atau cfg apa pun yang hanya dapat Anda jalani dan meninggalkan kesan yang baik (bukan untuk "hanya kesan" tetapi untuk reputasi dan posisi masa depan).
berdarah
28

Protokol Server Bahasa (LSP)

Protokol server Bahasa berisi fitur untuk mengganti nama simbol dengan cerdas di seluruh proyek:

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

Misalnya server bahasa berikut mendukung ini:

Anda dapat menemukan lebih banyak server bahasa di https://langserver.org/ .

Vim

Klien editor vim diperlukan untuk menggunakannya dalam vim. Ada opsi berikut:

  1. LanguageClient-neovim (membutuhkan rust) menyarankan pemetaan:

    nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
    
  2. coc.nvim (membutuhkan node.js) menyarankan pemetaan:

    " Remap for rename current word
    nmap <leader>rn <Plug>(coc-rename)
    
  3. Ale punya

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

    Ale tidak mendefinisikan keybindings apa pun. Ini harus dilakukan oleh pengguna.

  4. vim-lsp memberikan perintah berikut

    :LspRename
    

    Mirip dengan Ale, tidak ada pemetaan yang disarankan. Namun, tentu saja Anda dapat mendefinisikannya sebagai berikut

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

    ( <leader>rakan diganti dengan pilihan Anda; Saya tidak tahu yang mana yang disetujui oleh sebagian besar plugin)

  5. vim-lsc memiliki pemetaan default:

    'Rename': 'gR'
    

Lihat juga YouCompleteMe yang memfasilitasi LSP juga.

Neovim

Neovim memiliki dukungan bawaan awal untuk lsp sejak 13.11.2019

Lihat konfigurasi umum LSP https://github.com/neovim/nvim-lsp

Namun, saya tidak tahu cara kerja penggantian nama yang cerdas. Jika seseorang mengetahui hal ini, perbarui bagian ini.

Refactorings lainnya

Saya tidak tahu apakah ada rencana untuk protokol LSP untuk mendukung refactorings yang lebih kompleks, seperti mengubah struktur kelas, menambahkan parameter ke metode / fungsi atau memindahkan metode ke kelas yang berbeda. Untuk daftar refactorings lihat https://refactoring.com/catalog/ .

Hotschke
sumber
Sayangnya, dukungan untuk refactoring di LSP saat ini cukup lemah dibandingkan dengan yang canggih. github.com/Microsoft/language-server-protocol/issues/61
Mickael
2
AFAIK yang mengganti nama coc-renamehanya berfungsi pada buffer saat ini. Itu tidak memperbarui penggunaan nama yang diekspor secara global dalam proyek (di seluruh file).
oligofren
16

Python

Untuk bahasa python, plugin berikut menyediakan kemampuan mengganti nama 'pintar' untuk vim:

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

Keluarga-C

  1. Coba plugin Clighter untuk rename-refactoring untuk c-family. Ini didasarkan pada clang, tetapi ada batasan dan plugin ditandai sebagai usang.

    Pemetaan yang disarankan oleh Clighter adalah

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

    Catatan, plugin penerus clighter8 telah menghapus fungsionalitas penggantian nama di komit 24927db42 .

  2. Jika Anda menggunakan neovim, Anda dapat melihat penjepit plugin . Itu menyarankan

     nmap <silent> <Leader>r :call ClampRename()<CR>
    
BB Chung
sumber
5

Saya menulis plugin ini untuk refactoring generik. Masih membutuhkan banyak perbaikan. Suatu saat di masa mendatang saya akan mencoba untuk meninggalkan ctag yang mendukung dentang untuk refaktor C & C ++.

Luc Hermitte
sumber
5

Plugin YouCompleteMe (YCM) (20k bintang di github)

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

:h RefactorRename-new-name

Dalam jenis file yang didukung, perintah ini mencoba untuk melakukan penggantian nama semantik pengenal di bawah kursor. Ini termasuk mengganti nama deklarasi, definisi dan penggunaan pengenal, atau tindakan lain yang sesuai dengan bahasa. Perilaku spesifik ditentukan oleh mesin semantik yang digunakan.

Mirip dengan FixIt, perintah ini menerapkan modifikasi otomatis ke file sumber Anda. Operasi ganti nama mungkin melibatkan perubahan pada beberapa file, yang mungkin atau mungkin tidak terbuka di buffer Vim pada saat itu. YouCompleteMe menangani semua ini untuk Anda. Perilaku tersebut dijelaskan di bagian berikut.

Didukung dalam tipe file: c, cpp, objc, objcpp, cuda, java, javascript, skrip jenis, rust, cs

Secara default tidak ada pemetaan.

Hotschke
sumber
Jadi untuk sekarang ini hanya berfungsi untuk javascript, skrip dan java?
SR
Agar ini berfungsi di beberapa file di C-Family (menggunakan clangd) Anda perlu menambahkan ini ke .vimrc Anda: let g: ycm_clangd_args = ['-cross-file-rename']
jav
4

Mungkin bukan solusi yang paling elegan, tapi menurut saya sangat berguna: Saya menggunakan ECLIM untuk menghubungkan VIM dan Eclipse. Tentu saja semua pengeditan kode sumber saya dilakukan di VIM, tetapi ketika tiba waktunya untuk refactor, seseorang dapat memanfaatkan cababilitas unggul Eclipse dalam hal ini.

Cobalah.

fjrg76.dll
sumber
3

Faktor Plugin

Ada plugin vim lain yang didedikasikan untuk refactoring yang disebut factorus yang tersedia di github .

Saat ini (2017-12), ini mendukung bahasa

  • c,
  • java, dan
  • python.
Hotschke
sumber
2

Tempatkan kursor pada nama untuk refaktor dan tipe

gd(atau gDjika Anda memfaktorkan ulang variabel global).

Kemudian

cgn nama baru esc

dan

. satu kali atau lebih untuk memfaktor ulang kejadian berikutnya

atau

:%norm . untuk merefaktor semua kejadian di buffer sekaligus.

Geremia
sumber
1

Saya menulis banyak kode C / C ++ di vim. Refactoring yang paling umum saya lakukan adalah mengganti nama variabel, nama class, dll. Biasanya saya gunakan :bufdo :%s/source/dest/guntuk melakukan search / replace pada file, yang hampir sama dengan rename yang disediakan oleh big IDE.
Namun, dalam kasus saya, saya menemukan bahwa saya biasanya mengganti nama entitas yang serupa, dieja dalam kasus yang berbeda (yaitu CamelCase, snake_case, dll.), Jadi saya memutuskan untuk menulis utilitas kecil untuk membantu dengan jenis pencarian "smart-case" ini / ganti, itu di-host di sini . Ini adalah utilitas baris perintah, bukan plugin untuk vim, saya harap Anda dapat menemukannya berguna.

dkrikun.dll
sumber
0

Untuk pemfaktoran ulang, jika Anda menggunakan Unite (dan seharusnya), Anda dapat menggunakan vim-qfreplace dan membuatnya sangat mudah. Lihat video ini yang menunjukkan cara kerjanya. Setelah alur kerja Anda disetel, Anda dapat membuat beberapa pemetaan untuk mengoptimalkannya (alih-alih mengetik sebagian besar hal seperti di video).

BenC
sumber
0

Kombinasi dua plugin: vim-ripgrep , untuk menemukan seluruh file dan meletakkan hasilnya di jendela quickfix, dan quickfix-reflector untuk menyimpan perubahan langsung di jendela quickfix dan membuatnya secara otomatis menyimpan setiap perubahan di seluruh file.

Jason
sumber
0

Saya akan mempertimbangkan untuk menggunakan versi spacemacs dari emacs. Ini menggunakan mode yang sama dan sebagian besar penekanan tombol seperti Vim tetapi memiliki lebih banyak add-on karena sifatnya yang jernih. Jika Anda ingin memprogram dalam C ++ Anda cukup menambahkan lapisan c ++ dan sebagian besar IDE sudah disiapkan untuk Anda. Untuk bahasa interpretasi lainnya seperti python atau bash, Anda tidak perlu meninggalkan spacemac untuk menggunakannya. Mereka bahkan memiliki cara untuk menjalankan blok kode langsung di dalam teks Anda yang bekerja sangat baik untuk pemrograman terpelajar atau pemrograman yang dapat direproduksi di mana kode dan data berada dalam file yang sama. Keduanya dilakukan sebagai teks.

Spacemacs jauh lebih berat dalam memuat awal tetapi hal tambahan yang dapat Anda lakukan dengan itu sepadan dengan beberapa detik biaya startup. Satu mode organisasi lapisan layak untuk dicoba. Ini adalah daftar outliner, programmer, pengatur waktu / agenda harian terbaik yang pernah saya gunakan.

C. Kelly Osborn
sumber
0

Pergilah

  1. Alat Godoctor ( github ) mendukung beberapa kemampuan refactoring
  • Ganti nama
  • Fungsi Ekstrak
  • Ekstrak Variabel Lokal
  • Beralih var ⇔: =
  • Tambahkan stub Godoc

Ada plugin vim https://github.com/godoctor/godoctor.vim yang membuatnya tersedia

Dengan kursor dalam hal untuk mengganti nama:

:Rename <newname>

Menyoroti blok untuk diekstrak:

:Refactor extract newfunc
  1. vim-go

    • Mengganti nama pengenal dengan tipe aman yang tepat dengan :GoRename.
  2. Server bahasa gopls

Hotschke
sumber