Як замінити вкладки пробілами?


85

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

Проста заміна працює корисно лише тоді, коли немає провідних символів.


Якщо ви встановили vim-faq , ви можете отримати офлайн-відповідь там: :h vim-faqта шукайте /tab characters. Важко запам'ятовується тег :h faq-14.16.
Хоцке

Відповіді:


98

Ви можете використовувати :retabкоманду. З :help :retab

Замініть всі послідовності пробілів, що містять a, <Tab>новими рядками пробілу, використовуючи нове значення табстоп. Якщо ви не вказали новий розмір табуляту або він дорівнює нулю, Vim використовує поточне значення 'tabstop'. [...] 'expandtab'Увімкнено, Vim замінює всі вкладки відповідною кількістю пробілів.

Зауважте, що команда приймає діапазон, тому ви можете зробити візуальний вибір, а потім лише :retabвибрані рядки.


Класно! Працює швидко і просто!
DenisKolodin

2
як щодо надання прикладу?
Петро

23

Ви можете використовувати :retab, як зазначено, однак, це змінить усі вкладки на пробіли, а не лише вкладки на початку рядка

Отже, це (де символ вкладки):

if :; do
⇥echo "⇥hello"
end

змінюється на (де пробіл):

if :; do
␣␣echo "␣␣hello"
end

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

Отже, я написав невелику функцію для зміни лише вкладок / пробілів на початку рядка:

" :retab changes *everything*, not just start of lines
fun! Retab(expandtab)
    let l:spaces = repeat(' ', &tabstop)

    " Replace tabs with spaces
    if a:expandtab
        silent! execute '%substitute#^\%(' . l:spaces . '\)\+#\=repeat("\t", len(submatch(0)) / &tabstop)#e'
    " Replace spaces with tabs
    else
        silent! execute '%substitute#^\%(\t\)\+#\=repeat("' . l:spaces . '", len(submatch(0)))#e'
    endif
endfun

З цією версією вам потрібно вручну вказати expandtabу виклику функції (тобто :call Retab(1)змінити вкладки на пробіли), але ви також можете змінити його, щоб прийняти поточне значення &expandtab(як це вже робиться &tabstop), як і :retabце робиться. (Здається, я вважаю за краще вказати це вручну).


6
Також є відповідь на SO, який охоплює ретабіт тільки на початку рядка. Варто посилання через чіткість цього пояснення.
jalanb

Може хто - небудь пояснити , що робить лист aв if a:expandtabсередньому?
Джон cj

Також, схоже, умови зворотні (жарт: D?). Якщо у вас є set expandtab.vimrc, а потім autocmd BufWritePre * :call Retab(&expandtab)- відступ буде змінено на вкладки, а не пробіли.
Джон cj

11

Vim надає !retabкоманду, яка замінить усі послідовності <Tab>новими рядками пробілу, використовуючи нове значення табустопа (наприклад :set tabstop=2), але всі вкладки всередині рядків можуть бути змінені (наприклад, у програмі C, ви повинні використовувати, \tщоб цього уникнути)!

Таким чином, ви можете змінити всі вкладки на пробіли за допомогою наступної команди:

:%s/\t/  /g

або як запропонував @Shahbaz :

:%s/^\t\+/ g

Тож перетворюються лише вкладки, які використовуються в відступі.

Пояснення:

  • %представляє весь буфер / файл ( :help :%)
  • sозначає замінник ( :help sub-replace-special)
  • \tабо ^Iпозначає вкладку
  • - використовуйте стільки пробілів на одній вкладці
  • g - розшифровується як глобальний, і він конвертує кілька випадків виникнення вкладок в одному рядку

Потім , щоб виправити відступи весь файл, ви можете спробувати: gg=G. Перевірка: Повторне відступ коду з відступом для отримання детальної інформації.

Щоб використовувати пробіли за замовчуванням замість вкладок, вам потрібно додати у свій .vimrcфайл такі налаштування :

set tabstop=2     " (ts) width (in spaces) that a <tab> is displayed as
set expandtab     " (et) expand tabs to spaces (use :retab to redo entire file)
set shiftwidth=2  " (sw) width (in spaces) used in each step of autoindent (aswell as << and >>)

Альтернативним рішенням є використання tidy


Пов'язані:


1
Я б принаймні зробив %s/^\t\+/ gтак, щоб перетворилися лише вкладки, які використовуються в відступі. Крім того, це gg=Gможе бути катастрофічно з такими мовами, як пітон.
Шахбаз

3

Спробуйте скористатися:

expand -t 4 input_filename output_filename

expandце інструмент командного рядка для перетворення вкладок у пробіли, які можна запустити з оболонки або за допомогою :!expand.

Він знаходиться в POSIX, тому він повинен бути доступний у більшості систем. unexpandзробимо зворотне, до речі.


2
Що таке expand?
muru

Розгорнути - це вбудована термінальна команда для копіювання символу вкладки в пробіли. Детальний опис можна знайти за наступним посиланням. computerhope.com/unix/uexpand.htm
Ankit Shah

2
Якщо це зовнішні команди, вам слід згадати про це.
muru

Подальший опис додано. Перегляньте
Анкіт Шах

5
Ви також можете зробити це :%!expand -t 4всередині vim. А ще краще, ви також можете скористатися поточною опцією ширини зсуву: :exe '%!expand -t ' . &shiftwidth
EvergreenTree

1

Для повноти =може також використовуватися для виправлення відступів, після того як ви вказали, що вкладки замінені пробілами. У звичайному режимі це можна зробити, набравши текст :set expandtab. Потім їх =можна використовувати двома способами:

  • У візуальному режимі один =виправлятиме відступи вибраних блоків коду.
  • У звичайному режимі gg=Gбуде виправлено весь файл, де ggпереміщується курсор на початок файлу, потім =застосовується і Gпереміщується курсор до кінця файла.

Довідка: посилання


Це передбачає, що vim може перерахувати поточний відступ правильно (можливо, це не так) - також для неструктурованих файлів або коду, написаного в іншому редакторі з дещо іншими правилами відступу.
ideaman42

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