Как преобразовать пробелы в вкладки в Vim или Linux?

Я просмотрел несколько вопросов о переполнении стека для того, как конвертировать пробелы в табуляции, не обнаружив, что мне нужно. Кажется, есть больше вопросов о том, как конвертировать вкладки в пробелы, но я пытаюсь сделать обратное.

В Vim я пробовал :retab и :retab! без везения, но я верю, что они на самом деле предназначены для перехода от вкладок к пробелам.

Я попробовал как expand, так и unexpand в командной строке без везения.

Вот файл, о котором идет речь:

http://gdata-python-client.googlecode.com/hg-history/a9ed9edefd61a0ba0e18c43e448472051821003a/samples/docs/docs_v3_example.py

Как преобразовать ведущие пробелы в закладки с помощью Vim или оболочки?

Ответ 1

Используя Vim для расширения всех ведущих пробелов (более чем 'tabstop'), вы были правы в использовании retab, но сначала убедитесь, что 'expandtab' reset (:verbose set ts? et? является вашим другом). retab принимает диапазон, поэтому я обычно указываю % как "весь файл".

:set tabstop=2      " To match the sample file
:set noexpandtab    " Use tabs, not spaces
:%retab!            " Retabulate the whole file

Прежде чем делать что-либо подобное (особенно с файлами Python!), я обычно устанавливаю 'list', чтобы я мог видеть пробелы и изменения.

У меня есть следующее отображение в my .vimrc для этого:

nnoremap    <F2> :<C-U>setlocal lcs=tab:>-,trail:-,eol:$ list! list? <CR>

Ответ 2

1. Если у вас есть пробелы и нужны вкладки.

Во-первых, вам нужно решить, сколько пробелов будет иметь одну вкладку. Тем не менее, предположим, что у вас есть строки с ведущими 4 пробелами или 8... Чем вы понимаете, вы, вероятно, хотите, чтобы вкладка была 4 пробела. Теперь с этой информацией вы выполните:

:set ts=4
:set noet
:%retab!

Здесь есть проблема! Эта последовательность команд будет искать весь ваш текст, а не только пробелы в начале строки. Это означает, что строка типа: "Hey,␣this␣␣␣␣is␣4␣spaces" станет "Hey,␣this⇥is␣4␣spaces", но ее нет! его вкладка!.

Чтобы решить эту небольшую проблему, я рекомендую search вместо retab.

:%s/^\(^I*\)␣␣␣␣/\1^I/g

Этот поиск будет выглядеть во всем файле для любых строк, начиная с любого количества вкладок, за которым следуют 4 пробела, и заменяет его на любое количество вкладок, которые он нашел, плюс один.

Это, к сожалению, не будет запускаться сразу!

Сначала файл будет иметь строки, начинающиеся с пробелов. Затем поиск преобразует только первые 4 пробела в вкладку и позволяет следующее...

Вам нужно повторить команду. Сколько раз? Пока вы не получите pattern not found. Я не могу придумать способ автоматизировать процесс. Но если вы это сделаете:

`[email protected]:`

Возможно, вы сделали. Эта команда повторяет последний поиск/замену в 10 раз. Скорее всего, ваша программа будет иметь так много отступов. Если он есть, просто повторите еще раз @@.

Теперь, чтобы закончить ответ. Я знаю, что вы спросили об обратном, но вы никогда не знаете, когда вам нужно отменить все.

2. У вас есть вкладки и нужны пробелы.

Сначала определите, сколько пробелов вы хотите преобразовать в свои вкладки. Допустим, вы хотите, чтобы каждая вкладка была 2 пробела. Затем вы выполните:

:set ts=2
:set et
:%retab!

Это будет иметь ту же проблему со строками. Но поскольку его лучший стиль программирования не использует жесткие вкладки внутри строк, вы на самом деле делаете здесь хорошую работу. Если вам действительно нужна вкладка внутри строки, используйте \t.

Ответ 3

:%s/\(^\s*\)\@<=    /\t/g

Перевод: найдите каждый экземпляр из 4 последовательных пробелов (после символа =), но только если вся строка до этой точки является пробелом (это использует утверждение обратной связи с нулевой шириной, \@<=). Замените каждый найденный экземпляр символом табуляции.

Ответ 4

Изменяет все пробелы на вкладку :% S/\ s/\ т/г

Ответ 5

Bash для замены выделения 4 -spaces (есть два {4} в script) с вкладками во всех .py файлах в папке ./app (рекурсивно):

find ./app -iname '*.py' -type f \
    -exec awk -i inplace \
    '{ match($0, /^(( {4})*)(.*?)$/, arr); gsub(/ {4}/, "\t", arr[1]) }; { print arr[1] arr[3] }' {} \; 

Не модифицирует 4-пространства в середине или в конце.

Был протестирован под Ubuntu 16.0x и Linux Mint 18

Ответ 6

В моем случае у меня было несколько пробелов (поля были разделены одним или несколькими пробелами), которые я хотел заменить на вкладку. Следующие сделали это:

:% s/\s\+/\t/g

Ответ 7

Если у вас установлены GNU coreutils, рассмотрите %!unexpand --first-only или для вкладок с 4 пробелами рассмотрите %!unexpand -t 4 --first-only (--first-only присутствует только в случае, если вы случайно вызвали unexpand с --all).

Обратите внимание, что это заменит только пробелы, предшествующие заданным остановкам табуляции, а не пробелы, следующие за ними; вы не увидите визуальной разницы в vim, если не будете отображать вкладки более буквально; например, мой ~/.vimrc содержит set list listchars=tab:▸┈ (я подозреваю, именно поэтому вы думали, что unexpand не работает).

Ответ 8

Непоследовательное табуляция - это проклятие из ада для программистов Python. Я рекомендую разместить это в своем файле vimrc:

set tabstop=4
set et

Все вкладки становятся четырьмя пробелами. Вы можете конвертировать вкладки в пробелы в режиме командной строки vi, набрав

:1, $ s/\t/    /g  

Здесь есть четыре пробела. Вы также можете выбрать область в визуальном режиме и изменить эту подстановку, чтобы ограничить ее область.

Ответ 9

Простой Python Script:

import os

SOURCE_ROOT = "ROOT DIRECTORY - WILL CONVERT ALL UNDERNEATH"

for root, dirs, files in os.walk(SOURCE_ROOT):
    for f in files:
        fpath = os.path.join(root,f)
        assert os.path.exists(fpath)
        data = open(fpath, "r").read()
        data = data.replace("    ", "\t")
        outfile = open(fpath, "w")
        outfile.write(data)
        outfile.close()