Thay thế bằng vimscript thuần túy (không có `: s`)


11

Tôi có những điều sau đây trong vimrc của mình:

func! AddSpaceBeforeEqual()
  s/\([a-z)_0-9"'\[\]]\)=/\1 =/ge
endfunc

Tôi đang sử dụng vint để lint vimrc của mình và nhận được cảnh báo sau:

ProhibitCommandWithUnintendsSideEffect Tránh các lệnh có tác dụng phụ ngoài ý muốn. Tránh sử dụng: s [ubstolarship] vì nó di chuyển con trỏ và in thông báo lỗi. Thích các hàm (như search ()) phù hợp hơn với các script. Đối với nhiều lệnh vim, các hàm tồn tại làm điều tương tự với ít tác dụng phụ hơn. Xem: các hàm trợ giúp () để biết danh sách các hàm dựng sẵn. Hướng dẫn về Phong cách Vimscript của Google

Tuy nhiên, tôi không nghĩ rằng họ là một cách để thay thế mà không sử dụng :slệnh.

Ví dụ, search()hàm cung cấp các dòng khớp với một mẫu, nhưng không có cách nào để thay thế. Các substitute()chức năng hoạt động trên một chuỗi, và không thay thế trên toàn bộ một tập tin.

Tôi có nên tự mình thực hiện một phương pháp thay thế hay chúng là một cách thông minh hơn để viết lại chức năng của tôi?

Câu trả lời:


9

Lý do nó cảnh báo bạn về các tác dụng phụ ngoài ý muốn là vì :substitutekhông di chuyển con trỏ và ghi đè lên tìm kiếm trước đó (nếu được sử dụng bên ngoài hàm) . Tuy nhiên, điều này không có nghĩa là bạn không nên sử dụng nó, vì bạn có thể đảo ngược tác dụng phụ của :substitute. Ví dụ, đây là một hàm tôi đã thực hiện sử dụng lệnh thay thế để loại bỏ khoảng trắng theo sau:

function! StripTrailingWhitespace()
    " Save cursor position
    let l:save = winsaveview()
    " Remove trailing whitespace
    %s/\s\+$//e
    " Move cursor to original position
    call winrestview(l:save)
    echo "Stripped trailing whitespace"
endfunction

Lưu ý rằng bạn cũng có thể sử dụng :marklệnh để lưu vị trí con trỏ, nhưng điều đó cũng có nghĩa là bạn sẽ ghi đè lên dấu bạn quyết định sử dụng. Tôi chưa từng sử dụng vint trước đây, nhưng một mẹo nhỏ về việc sử dụng thuốc là bạn có thể đưa ra cảnh báo của họ bằng một hạt muối. Trong trường hợp này, đúng là :substitutecó tác dụng phụ, nhưng chúng là tác dụng phụ có thể ngăn ngừa được. Thêm vào đó, thực sự không có cách nào tốt hơn để thực hiện tìm kiếm và thay thế trong một tệp nào.


6
Thuật ngữ tìm kiếm được sử dụng lần cuối được tự động khôi phục sau khi rời khỏi một chức năng, do đó, việc lưu và khôi phục không cần thiết khi sử dụng nó trong một chức năng. Xem:help function-search-undo
Martin Tournoij

1
thay vì sử dụng winaveview () / winrestview () thay vì con trỏ ()
Christian Brabandt

8

Đây là một triển khai đơn giản của chức năng của bạn, được viết bằng substitute():

function! AddSpaceBeforeEqualInWholeBuffer()
    let l = 1
    for line in getline(1,"$")
        call setline(l, substitute(line, '\([^= ]\)=', '\1 =', "g"))
        let l = l + 1
    endfor
endfunction

Điều chỉnh mô hình tìm kiếm theo sở thích.


1

Các :slệnh là một cách tiếp cận Vimscript tinh khiết.

Tôi đoán là cảnh báo chỉ có nghĩa là, con trỏ rất có thể sẽ bị sử dụng sai sau khi sử dụng nó (mà bạn có thể tránh được bằng cách sử dụng winsaveview()chức năng trước và giao tiếp winrestview()sau khi sử dụng). Ngoài ra, bạn cần phải chăm sóc các lỗi có thể xảy ra. Điều này thường được xử lý bằng cách sử dụng ecờ. Ngoài ra, người ta cần quan tâm đến một số cài đặt như gdefaultcài đặt, trong đó đảo ngược ý nghĩa của gcờ.

Người ta cần quan tâm đến những chi tiết cụ thể đó và đó có lẽ là nguyên nhân sâu xa của những cảnh báo đó. Nhưng điều đó không có nghĩa là tránh sử dụng :slệnh. Hoàn toàn ổn khi sử dụng :slệnh, nếu bạn muốn thay thế một cái gì đó trong bộ đệm hiện tại.

(Lưu ý, tất nhiên người ta có thể lặp qua tất cả các dòng và sử dụng phương pháp tìm kiếm () / getline () / setline (). Nhưng điều đó thường chậm hơn.)

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.