Ponowne wcięcie źle wciętego kodu

39

Podoba mi się funkcja inteligentnego wcięcia Vima, która pozwala mi tworzyć dobrze wcięte bloki kodu.

Regularnie kopiuję / wklejam kod do buforów, ale kod ten jest często źle sformatowany.

Idealne byłoby „ponowne przetworzenie” kodu za pomocą systemu inteligentnego wcięcia.

Czy coś takiego jest możliwe?

Na przykład, w jaki sposób „naprawiłbyś” następujący kod (wyciąg z większego bloku - nie chcę naprawiać każdej linii ręcznie ...):

    else 
                {
                        m[c] = 5;
                Finished = true;
std::cout<<"(ID,R,E)"<<"-->"<<"("<<g[c]<<","<<r[c]<<","<<E1 <<")"<< std::endl;
std::cout << "\n"<<"finish-->" << r[c] << "\t" <<"E1-->"<< E1 <<"\n" ;
                }
        }
rolfl
źródło
1
Czy mówisz o wklejaniu kodu, który był początkowo źle wcięty lub poprawnie wcięty, który zmienia się po wklejeniu go do Vima?
jamessan
Wklejony kod jest na początku słabo wcięty. Pozwól mi podać przykład ....
rolfl

Odpowiedzi:

48

Robię to na dwa sposoby.

Pasta dostosowana do wcięcia

Po pierwsze, jeśli kod w buforze jest sformatowany, ale na innym poziomie wcięcia, używam ]pzamiast tego p, który wkleja kod w obecnym stanie, ale z wcięciem przesuniętym tak, że pierwszy wklejony wiersz ma taką samą głębokość jak wiersz I jestem włączony.

Źródło EG skopiowane do bufora

while (1) {
    dostuff();
}

EG wynik wklejenia go ]p

int myfunc() {
    int i = 5; /* Cursor on this line before paste */
    while (1) {
        dostuff();
    }
 }

vim umieszcza ten czas na tym samym poziomie wcięcia co int i. Jest to szybkie, ale działa tylko wtedy, gdy skopiowany kod jest odpowiednio wcięty w sobie.

Sformatuj po wklejeniu

=Operator w vim formatuje kod na podstawie skonfigurowanych reguł formatowania. W przypadku krótkich fragmentów wklejania przejdę do trybu wizualnego v, wybierz linie, które właśnie wkleiłem, a następnie naciśnij, =aby je ponownie sformatować.

W przypadku większych past korzystam z faktu, że kursor przechodzi do pierwszej wklejonej linii, a vim mówi coś w rodzaju „84 kolejnych linii”. Mogę następnie wejść, 84==aby ponownie napełnić te 84 wiersze (oczywiście zastąp 84 liczbą wierszy, które faktycznie wkleiłeś).

Referencje

:help ]p dla skorygowanej pasty wcięcia

:help =Pokrywy ={motion}, [count]==a {Visual}=do filtrowania przez zwyczaju lub wbudowane wcięć zasad

John O'M.
źródło
6
Możesz ładnie wybrać kod wklejony w trybie wizualnym za pomocą `[v`]
craigp
1
@Badger Dla wyjaśnienia, czy to jest wspornik backtick-v-backtick-bracket?
phatskat
1
tak .. textarea wariował na temat backticks, więc nie mogłem umieścić go w bloku kodu: P
craigp
Operator = w vim ponownie formatuje kod w oparciu o skonfigurowane reguły formatowania , dałbym +100, gdybym mógł. Mógłbym zaoszczędzić dni.
Wossname
1
Używam <control + R> ", aby wkleić, więc nie muszę wychodzić z trybu wstawiania. Co to jest] p równoważne dla <control + R>"?
A --- B
15

=Komenda może być użyta do reindent.

Podobnie jak większość poleceń w trybie normalnym, można go zastosować do ruchu, dzięki czemu można ponownie wkleić właśnie wklejony kod =']. Powoduje to przejście od bieżącej pozycji kursora do ']znaku, który jest ostatnim wierszem pasty.

= może być również używany z trybu wizualnego.

Kolejnym przydatnym poleceniem jest ]pwklejanie na tym samym poziomie wcięcia co bieżąca linia. Może to pomóc wkleić poprawnie wcięty tekst, chociaż na innej głębokości wcięcia, zgodnie z otaczającym tekstem.

jamessan
źródło
7

Użycie =ap (mnemonic to „formatuj akapit”) spowoduje, że vim spróbuje automatycznie sformatować bieżący akapit.

Jeśli chcesz zwrócić szczególną uwagę na to, co potencjalnie sformatujesz, może okazać się zdrowsze i szybsze w użyciu, vapaby wizualnie wybrać bieżący akapit (dając wizualne wskazanie tego, co jest formatowane), a następnie =. Uważam to za przydatne w plikach, w których wiem, że vim nieprawidłowo sformatuje i nie chcę błędnie formatować innych linii.

davidlowryduda
źródło
4

Aby ponownie wprowadzić plik znajdujący się już w buforze, użyj gg=G: Zobacz Napraw wcięcie

Aby ponownie wprowadzić część pliku, do =filtra można zastosować różne granice (na przykład ==naprawia tylko bieżącą linię).

Aby pozostawić niezmienione wcięcie podczas wklejania tekstu, :set pastezanim wkleisz tekst do bufora, zapobiegnie to vimowi przed automatycznym wcięciem właśnie wklejonego tekstu. Po wklejeniu rzeczy możesz wrócić, set :nopastegdy skończysz. Zobacz vimdoc tutaj .

Jeśli często wklejasz różne rzeczy, dobrym pomysłem byłoby skorzystanie z tej wskazówki na VimWiki i skonfigurowanie klucza do przełączania trybu „wklejania” poprzez dodanie następujących wierszy do .vimrc:

nnoremap <F2> :set invpaste paste?<CR>
set pastetoggle=<F2>
set showmode

Następnie możesz nacisnąć, <F2>aby przełączyć tryb wklejania. vim wyświetli słowa „WKLEJ” w wierszu stanu, gdy aktywny jest tryb wklejania.

Bhargav Bhat
źródło
2
To pytanie nie dotyczy wklejania kodu z wcięciami, lecz naprawiania źle wciętego kodu.
rolfl
4
Nie widziałem opublikowanego komentarza. Nadal możesz jednak użyć gg=Gdo ponownego zindeksowania całego pliku.
Bhargav Bhat
@rolfl Zazwyczaj zaczynam w takich przypadkach: gg=Gnastępnie spójrz na części, które vimpopełniły błąd.
muru
Jeśli chcesz mieć większą kontrolę (lub zmniejszyć powtarzające się problemy), rozważ dodanie automatycznego polecenia, aby wywołać narzędzie do formatowania kodu, na przykład astylepodczas zapisywania bufora. Zobacz to pytanie w SO, aby uzyskać szczegółowe informacje.
Bhargav Bhat
2

Aby ponownie automatycznie wciąć cały blok stężonego lub nawiasowego bloku, umieść kursor na tej samej linii, w której znajduje się nawias, i spróbuj =%. Aby zmienić szerokość przesunięcia, użyj np :set sw=2.

Jeśli to nie zadziała zgodnie z oczekiwaniami, aby ręcznie zmniejszyć wcięcie ( nieobecne ), spróbuj <%powtórzyć za pomocą .(jeśli to konieczne). Użyj >%na odwrót.

Więc:

else
       {
         // some code
       }

staje się:

else
{
  // some code
}

W przypadku konkretnego kodu, aby ponownie automatycznie wciąć jeden lub kilka wierszy, spróbuj:

  • == w celu ponownego wcięcia bieżącej linii
  • 5== do ponownego wcięcia 5 linii

Aby ręcznie zwiększyć / zmniejszyć wcięcie dla jednej linii lub kilku linii, spróbuj:

  • << aby zmniejszyć wcięcie bieżącej linii spacjami shiftwidth
  • 5<< aby zmniejszyć wcięcie 5 linii spacjami shiftwidth
  • >> wcięcie bieżącej linii spacjami shiftwidth
  • 5>> wciąć 5 wierszy spacjami shiftwidth
  • . w razie potrzeby powtórzyć

Wcięcie można także wykonać w trybie wizualnym ( v), wybierając tekst i naciskając =(automatyczne wcięcie), <(zmniejszenie wcięcia) lub >(wcięcie).

Inną sztuczką jest do prawidłowego wcięcia całego pliku przez: gg=G.

Jeśli masz tabulatory zamiast spacji, użyj:, :retabktóry zastąpi wszystkie tabulatory spacjami (zobacz: Jak zamienić tabulatory spacjami? ).


W przypadku metod zewnętrznych możesz wypróbować:

  • pythonTidy for reformat code Python, np .:

    :%!pythonTidy
    

Związane z:

kenorb
źródło
1

Niedawno zainstalowałem vim-pasta ( https://github.com/sickill/vim-pasta ), co wydaje się poprawiać wcięcie kodu podczas wklejania. W README jest także dobra dyskusja na temat różnych strategii wklejania kodu.

Rob Warner
źródło
1

W istniejących odpowiedziach jest już wiele rzeczy. Chciałbym tylko dodać jedno mapowanie, którego używam bardzo często do wcięć.

nnoremap <Leader>i  mzgg=G`z

Widziałem trochę vimrc z tym zmapowanym na ===.

Tak czy inaczej, jest to świetne mapowanie i używam go prawie za każdym razem, szczególnie gdy wklejam kod skopiowany z innego miejsca.

Lub jeszcze lepiej umieść to w taki autocmdsposób, aby Vim wciął go tuż przed zapisaniem zmian na dysku.

Durga Swaroop
źródło