Заміна чистим vimscript (без `: s`)


12

У моєму vimrc є таке:

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

Я використовую vint, щоб обличити свій vimrc, і я отримав таке попередження:

ProhibitCommandWithUnintendedSideEffect Уникайте команд з непередбачуваними побічними ефектами. Уникайте використання: s [ubstitute], оскільки він переміщує курсор і друкує повідомлення про помилки. Кращі функції (наприклад, пошук ()) краще підходять для сценаріїв. Для багатьох команд vim існують функції, які роблять те саме, що має менше побічних ефектів. Див.: Довідкові функції () для переліку вбудованих функцій. Посібник зі стилю Google Vimscript

Однак я не думаю, що вони є способом зробити заміну без використання :sкоманди.

Наприклад, search()функція дає лінії, що відповідають шаблону, але немає можливості зробити підміну. substitute()Функція працює на шнурку, і не підміняти на весь файл.

Чи повинен я сам реалізувати метод заміни, чи це розумніший спосіб переписати мою функцію?

Відповіді:


10

Ось спрощена реалізація вашої функції, написана на substitute():

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

Відрегулюйте шаблон пошуку за смаком.


10

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

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

Зауважте, що ви також можете скористатися :markкомандою для збереження позиції курсору, але це також означає, що ви будете перезаписати позначку, яку ви вирішили використовувати. Я раніше не використовував vint, але одна порада на підводках - це те, що ви можете попередити їх із зерном солі. У цьому випадку правда, що :substituteце має побічні ефекти, але вони є побічними ефектами, які можна запобігти. Крім того, дійсно немає кращого способу пошуку та заміни файлу в будь-якому випадку.


6
Останній використаний пошуковий термін автоматично відновлюється після виходу з функції, тож збереження та відновлення, яке не потрібно вимагати при використанні його всередині функції. Дивіться:help function-search-undo
Мартін Турной

1
скоріше використовуйте winsaveview () / winrestview () замість курсору ()
Christian Brabandt

1

:sКоманда є чисто Vimscript підхід.

Я думаю, що попередження означає лише те, що курсор, швидше за все, буде невпорядкований після його використання (що можна обійти, скориставшись winsaveview()функцією до і командою winrestview()після її використання). Також потрібно подбати про можливі помилки, які можуть виникнути. Зазвичай це обробляється за допомогою eпрапора. Також потрібно подбати про деякі параметри, такі як gdefaultналаштування, яке перевертає значення gпрапора.

Треба подбати про ці особливості, і це, мабуть, першопричина цих попереджень. Але це не означає уникати використання :sкоманди. Цілком нормально використовувати :sкоманду, якщо ви хочете щось замінити в поточному буфері.

(Зверніть увагу, можна, звичайно, переглядати всі рядки і використовувати підхід search () / getline () / setline (). Але це зазвичай повільніше.)

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