Tái cấu trúc trong Vim


99

Tất nhiên thực tế là bạn có thể cấu trúc lại trên IDE là vô giá đối với nhiều người, tôi hầu như không bao giờ làm điều đó khi tôi viết mã nhưng tôi có thể cố gắng làm điều đó khi chỉnh sửa một số mã nguồn của người khác. Làm thế nào để bạn hoàn thành một nhiệm vụ nhỏ như vậy trên nhiều tệp trong Vim?

Tôi đã tìm thấy plugin này để tái cấu trúc lại Ruby, nhưng còn ngôn ngữ "bất kỳ" thì sao?


2
Tái cấu trúc rất cụ thể về ngôn ngữ. Bạn cần tìm kiếm các tiện ích bổ sung cụ thể cho từng ngôn ngữ mà bạn quan tâm. Có thể bạn sẽ tìm thấy các tiện ích bổ sung cho một số và không cho những ngôn ngữ khác. Nếu có một thứ bạn muốn và không thể tìm thấy, thì nếu bạn cảm thấy tham vọng, bạn có thể thử viết một cái đó, sử dụng một tiện ích bổ sung hiện có cho một ngôn ngữ tương tự khác làm điểm khởi đầu.
Steve Jorgensen

2
VIM được thiết kế xoay quanh việc chỉnh sửa các tệp đơn lẻ và có thể là các tệp trong một thư mục - không phải các dự án . Nhiều cấu trúc lại được IDE hỗ trợ sẽ tác động đến các tệp trong toàn bộ dự án (ví dụ: đổi tên một lớp). Tôi nghĩ sẽ rất khó để có được "quyền" này với một biên tập viên như (g) VI (m), đến mức mà tôi nghĩ rằng một công ty hoặc một dự án lớn sẽ phải thực hiện nó. Về cơ bản, họ sẽ phải phân tích cú pháp từng ngôn ngữ để tránh thực hiện các thay thế chuỗi đơn giản và dễ bị lỗi (ctags cung cấp một số điều này), cũng như các loại dự án tương ứng (để biết tệp nào cần chỉnh sửa).
Merlyn Morgan-Graham

1
Cảm ơn các ý kiến ​​đóng góp, tôi nghĩ rằng đây là lúc mọi thứ bắt đầu trở nên phức tạp và việc cố gắng bẻ cong VIM thành IDE không phải là một giải pháp hay để chỉ sử dụng một chương trình để chỉnh sửa nhiều ngôn ngữ. Tôi thực sự không muốn từ bỏ VIM do một số tính năng "nâng cao" có sẵn trên IDE.
Helmut Granda

@ MerlynMorgan-Graham - Một số người chỉ giữ mã của họ trong một vài tệp (lớn, có thể là). Tránh hoàn toàn vấn đề này.
Rook

7
@ldigas: Điều đó sẽ giải quyết được vấn đề. Nhưng nó hoàn toàn chống lại các thông lệ được khuyến nghị cho một số ngôn ngữ (ví dụ như Java). Về cơ bản, mã uốn để phù hợp với nhu cầu của công cụ, khi nó thực sự phải theo cách khác.
Merlyn Morgan-Graham

Câu trả lời:


78

Tôi đồng ý với mô hình 'Vim không phải là IDE'. Nhưng đôi khi không có IDE. Đây là những gì tôi sử dụng trong những tình huống đó:

: grep,: vimgrep,: Ag,: Ggrep

Cấu trúc lại cấu trúc liên quan nhiều hơn đến các thay thế thông thường mà tôi thường sử dụng : grep trên cây dự án của tôi và sau đó ghi lại macro để thực hiện tái cấu trúc -: g và: s không phải là brainers. Thông thường, nó sẽ cho phép tôi nhanh chóng sửa đổi một số lượng lớn các tệp với rất ít nỗ lực. Thành thật mà nói, tôi sử dụng phương pháp này nhiều hơn bất kỳ phương pháp nào khác.

Tùy thuộc vào quy trình làm việc của bạn, các lệnh tích hợp có thể chậm / bất tiện. Nếu bạn sử dụng git, thì bạn sẽ muốn sử dụng plugin Fugitive tuyệt vời và :Ggreplệnh của nó để chỉ tìm kiếm các tệp được chọn vào git. Tôi cũng thích Silver Searcher vì tốc độ của nó.

: argdo,: cdo và: bufdo

: cdo: argdo rất tiện lợi để thực hiện các lệnh vim trên một tập hợp các tệp.

dòng lệnh

Khi việc xác định danh sách các tệp cần thay đổi khó hơn, :vimgreptôi sử dụng dòng lệnh grep / find lệnh để quản lý chặt chẽ hơn danh sách tệp mà tôi cần cấu trúc lại. Lưu danh sách vào tệp văn bản và sử dụng :evà kết hợp các bản ghi macro để thực hiện các thay đổi tôi cần thực hiện.

Tôi thấy rằng kỹ năng ghi macro của mình càng ít bị hỏng thì tôi thấy Vim càng hữu ích hơn cho việc tái cấu trúc: cảm thấy thoải mái khi lưu / khôi phục từ các thanh ghi, tăng / giảm biến bộ đếm thanh ghi, dọn dẹp / lưu các bản ghi macro vào tệp để sử dụng sau này, v.v.


Cập nhật

Kể từ khi viết thêm video này cho các phương pháp tôi mô tả đã được xuất bản trên vimcasts.org (Tôi khuyến khích bạn xem TẤT CẢ các Vimcast! ). Để tái cấu trúc, hãy xem những cái này:

Vimgolf cũng là một cách tuyệt vời để luyện tập.

Sự phổ biến của các máy chủ Giao thức Máy chủ Ngôn ngữ kể từ khi tôi viết câu trả lời này cũng đã mang lại một số khả năng tái cấu trúc cho Vim (và các trình soạn thảo khác). IMO chúng còn lâu mới có khả năng cân bằng khả năng tái cấu trúc mà bạn sẽ thấy trong IDE được xây dựng có mục đích (tôi sử dụng chúng, và thích coc và ALE hơn). Xem các câu trả lời khác về câu hỏi này để biết thêm thông tin!


12
Tái cấu trúc không chỉ là so khớp mẫu, đó là lý do tại sao IDE cần thiết để tự động hóa việc này một cách an toàn. Rõ ràng, bạn có thể làm điều đó theo cách thủ công, nhưng xem xét các tùy chọn có sẵn và hầu hết các trường hợp sẽ an toàn hơn khi làm thủ công, tại sao bạn lại cân nhắc bất kỳ tùy chọn nào khác?
Cutberto Ocampo

1
@CutbertoOcampo Tôi đồng ý với bạn ở một mức độ nào đó: tùy thuộc vào vô số khía cạnh của một dự án (cấu trúc, (các) ngôn ngữ, kỹ năng và nguồn lực của nhân viên, có thể có một công cụ tái cấu trúc tuyệt vời áp dụng cho vấn đề của bạn. Câu trả lời của tôi áp dụng cho các tình huống khi điều đó không đúng và bạn muốn giải quyết vấn đề trong Vim.
dsummersl

2
điều đó tốt thôi, tôi hiểu mọi người có thể cảm thấy thoải mái hơn khi sử dụng các công cụ ưa thích lâu năm của họ và có một số bản hack có thể hoạt động thực sự tốt, có thể tốt hơn bất kỳ IDE nào hiện có, nhưng không phải -box giải pháp Tôi muốn nói rằng một IDE thực tế sẽ hoạt động tốt hơn cho hầu hết người dùng. Tôi đang suy nghĩ về một loại tình huống 80-20% (thậm chí nhiều hơn, với sự cân bằng có lợi cho IDE).
Cutberto Ocampo

1
Có một lý tưởng cho thực tế mọi ngôn ngữ. Cố gắng tái cấu trúc bằng vim hoặc regex nghe có vẻ điên rồ. Tại sao bạn thậm chí sẽ thử?
cuộn vào

1
@rolls đủ mạnh để lấy được cỗ máy cần thiết của đồng nghiệp ngẫu nhiên không-phải-ý-tưởng của bạn hoặc bất cứ thứ gì mà bạn chỉ có thể sống cùng và để lại ấn tượng tốt xung quanh (không phải vì "ấn tượng" mà là danh tiếng và vị trí trong tương lai).
đẫm máu

24

Giao thức máy chủ ngôn ngữ (LSP)

Giao thức máy chủ ngôn ngữ chứa tính năng đổi tên thông minh các ký hiệu trong một dự án:

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

Ví dụ: máy chủ ngôn ngữ sau hỗ trợ điều này:

Bạn có thể tìm thêm máy chủ ngôn ngữ tại https://langserver.org/ .

Vim

Một ứng dụng khách soạn thảo vim là cần thiết để sử dụng chúng trong vim. Các tùy chọn sau tồn tại:

  1. LanguageClient-neovim (yêu cầu gỉ) đề xuất ánh xạ:

    nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
    
  2. coc.nvim (yêu cầu node.js) đề xuất ánh xạ:

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

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

    Ale không xác định bất kỳ liên kết chính nào. Điều này phải được thực hiện bởi người dùng.

  4. vim-lsp cung cấp lệnh sau

    :LspRename
    

    Tương tự như Ale, không có ánh xạ nào được đề xuất. Tuy nhiên, tất nhiên bạn có thể định nghĩa một như sau

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

    ( <leader>rsẽ được thay thế theo lựa chọn của bạn; tôi không biết phần lớn plugin đồng ý với cái nào)

  5. vim-lsc có ánh xạ mặc định:

    'Rename': 'gR'
    

Xem thêm YouCompleteMe cũng tạo điều kiện cho LSP.

Neovim

Neovim có hỗ trợ nội trang ban đầu cho lsp kể từ ngày 13.11.2019

Xem các cấu hình phổ biến của LSP https://github.com/neovim/nvim-lsp

Tuy nhiên, tôi không thể tìm ra cách đổi tên thông minh hoạt động. Nếu ai đó biết điều này, vui lòng cập nhật phần này.

Tái cấu trúc khác

Tôi không biết liệu có kế hoạch nào cho giao thức LSP để hỗ trợ các cấu trúc lại phức tạp hơn hay không, chẳng hạn như thay đổi cấu trúc lớp, thêm tham số vào phương thức / chức năng hoặc chuyển một phương thức sang một lớp khác. Để biết danh sách tái cấu trúc, hãy xem https://refactoring.com/catalog/ .


Thật không may, việc hỗ trợ tái cấu trúc trong LSP hiện khá yếu so với hiện đại. github.com/Microsoft/language-server-protocol/issues/61
Mickael

AFAIK việc đổi tên coc-renamechỉ hoạt động trên bộ đệm hiện tại. Nó không cập nhật việc sử dụng tên đã xuất trên toàn cầu trong dự án (trên các tệp).
oligofren,

15

Python

Đối với ngôn ngữ python, các plugin sau cung cấp khả năng đổi tên 'thông minh' cho vim:

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

13

C-Family

  1. Hãy thử plugin Clighter để đổi tên-tái cấu trúc cho họ c. Nó dựa trên clang, nhưng có những hạn chế và plugin được đánh dấu là không được dùng nữa.

    Ánh xạ do Clighter đề xuất mới

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

    Lưu ý, plugin kế nhiệm clighter8 đã loại bỏ chức năng đổi tên trong cam kết 24927db42 .

  2. Nếu bạn sử dụng neovim, bạn có thể xem qua kẹp plugin . Nó gợi ý

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

5

Tôi đã viết plugin này để tái cấu trúc chung. Nó vẫn cần nhiều cải tiến. Đôi khi trong tương lai, tôi sẽ cố gắng bỏ ctags để ủng hộ tiếng kêu cho các cấu trúc lại C & C ++.


4

Có thể không phải là giải pháp thanh lịch nhất, nhưng tôi thấy nó rất tiện dụng: Tôi sử dụng ECLIM để kết nối VIM và Eclipse. Tất nhiên tất cả việc chỉnh sửa mã nguồn của tôi được thực hiện trong VIM, nhưng khi đã đến lúc cấu trúc lại, người ta có thể tận dụng các khả năng vượt trội của Eclipse trong vấn đề này.

Hãy thử một lần.


3

Plugin Factorus

Có một plugin vim khác dành riêng cho việc tái cấu trúc có tên là factorus , có sẵn trên github .

Hiện tại (2017-12), nó hỗ trợ các ngôn ngữ

  • c,
  • java và
  • con trăn.

3

Plugin YouCompleteMe (YCM) (20k sao trên github)

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

:h RefactorRename-new-name

Trong các loại tệp được hỗ trợ, lệnh này cố gắng thực hiện đổi tên theo ngữ nghĩa của số nhận dạng dưới con trỏ. Điều này bao gồm đổi tên các khai báo, định nghĩa và cách sử dụng của số nhận dạng hoặc bất kỳ hành động nào khác phù hợp với ngôn ngữ. Hành vi cụ thể được xác định bởi công cụ ngữ nghĩa đang sử dụng.

Tương tự như FixIt, lệnh này áp dụng các sửa đổi tự động cho các tệp nguồn của bạn. Thao tác đổi tên có thể liên quan đến các thay đổi đối với nhiều tệp, có thể mở hoặc không thể mở trong bộ đệm Vim tại thời điểm đó. YouCompleteMe xử lý tất cả những điều này cho bạn. Hành vi được mô tả trong phần sau.

Được hỗ trợ trong các loại tệp: c, cpp, objc, objcpp, cuda, java, javascript, stylescript, gỉ, cs

Theo mặc định không có ánh xạ.


Vì vậy, bây giờ điều này chỉ hoạt động cho javascript, typecript và java?
SR

2

Đặt con trỏ vào tên để cấu trúc lại và nhập

gd(hoặc gDnếu bạn đang cấu trúc lại một biến toàn cục).

Sau đó

cgn tên mới esc

. một hoặc nhiều lần để cấu trúc lại (các) lần xuất hiện tiếp theo

hoặc là

:%norm . để cấu trúc lại tất cả các lần xuất hiện trong bộ đệm cùng một lúc.


1

Tôi viết rất nhiều mã C / C ++ trong vim. Việc tái cấu trúc phổ biến nhất mà tôi thực hiện là đổi tên các biến, tên lớp, v.v. Thông thường, tôi sử dụng:bufdo :%s/source/dest/g để thực hiện tìm kiếm / thay thế trong tệp, điều này gần giống như đổi tên do IDE lớn cung cấp.
Tuy nhiên, trong trường hợp của tôi, tôi thấy rằng tôi thường đổi tên các thực thể tương tự, được đánh vần trong các trường hợp khác nhau (ví dụ như CamelCase, solid_case, v.v.), vì vậy tôi quyết định viết một tiện ích nhỏ để trợ giúp với loại tìm kiếm "trường hợp thông minh" này / thay thế, nó được lưu trữ ở đây . Nó là một tiện ích dòng lệnh, không phải là một plugin cho vim, tôi hy vọng rằng bạn có thể thấy nó hữu ích.


0

Để tái cấu trúc, nếu bạn đang sử dụng Unite (và bạn nên làm như vậy), thì bạn có thể sử dụng vim-qfreplace và thực hiện nó cực kỳ dễ dàng. Kiểm tra video này để minh họa cách nó hoạt động. Sau khi quy trình làm việc của bạn được thiết lập, bạn có thể thực hiện một số ánh xạ để tối ưu hóa quy trình đó (thay vì nhập hầu hết những thứ như trong video).


0

Sự kết hợp của hai plugin: vim-ripgrep , để tìm trên các tệp và đưa kết quả vào cửa sổ Quickfixquickfix-phản xạ để lưu các thay đổi ngay trong cửa sổ quickfix và tự động lưu từng thay đổi trên các tệp.


0

Tôi sẽ cân nhắc sử dụng phiên bản emacs không gian. Nó sử dụng các chế độ và hầu hết các tổ hợp phím giống như Vim nhưng có nhiều tiện ích hơn vì tính chất ngọng. Nếu bạn muốn lập trình bằng C ++, bạn chỉ cần thêm lớp c ++ và hầu hết IDE đã được thiết lập cho bạn. Đối với các ngôn ngữ thông dịch khác như python hoặc bash, bạn không cần để lại dấu cách để sử dụng chúng. Họ thậm chí còn có một cách để chạy các khối mã trực tiếp trong văn bản của bạn, điều này hoạt động tuyệt vời cho lập trình hiểu biết hoặc lập trình có thể tái tạo trong đó mã và dữ liệu nằm trong cùng một tệp. Cả hai đều được thực hiện dưới dạng văn bản.

Spacemacs nặng hơn nhiều khi tải ban đầu nhưng những thứ bổ sung bạn có thể làm với nó đáng giá vài giây so với chi phí khởi động. Chế độ tổ chức một lớp rất đáng để thử. Đó là danh sách phác thảo, lập trình viên, hẹn giờ / việc làm tốt nhất mà tôi từng sử dụng.


0

Đi

  1. Công cụ Godoctor ( github ) hỗ trợ một số khả năng tái cấu trúc
  • Đổi tên
  • Chức năng trích xuất
  • Trích xuất biến cục bộ
  • Chuyển đổi var ⇔: =
  • Thêm sơ khai Godoc

Có một plugin vim https://github.com/godoctor/godoctor.vim cung cấp chúng

Với con trỏ để đổi tên:

:Rename <newname>

Đánh dấu khối để giải nén:

:Refactor extract newfunc
  1. vim-go

    • Đổi tên chính xác loại an toàn cho các số nhận dạng với :GoRename.
  2. Máy chủ ngôn ngữ gopls

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.